Provided by: manpages-de-dev_4.21.0-2_all bug

BEZEICHNUNG

       ptrace - Prozessverfolgung

BIBLIOTHEK

       Standard-C-Bibliothek (libc, -lc)

ÜBERSICHT

       #include <sys/ptrace.h>

       long ptrace(enum __ptrace_request Anfrage, pid_t PID,
                   void *Adresse, void *Daten);

BESCHREIBUNG

       Der  Systemaufruf ptrace() stellt ein Mittel bereit, wodurch ein Prozess (der »Verfolger«) die Ausführung
       eines anderen Prozesses (des »verfolgten Prozesses«) beobachten und  steuern  kann  und  seinen  Speicher
       sowie  die  Register untersuchen und ändern kann. Er wird in erster Linie benutzt, um Fehlersuche mittels
       Haltepunkten zu implementieren und Systemaufrufe zu verfolgen.

       Ein verfolgter Prozess muss zuerst an den Verfolger angehängt werden. Anhängen und  nachfolgende  Befehle
       bestehen  pro  Thread:  In  einem  Prozess  mit  mehreren  Threads kann jeder Thread individuell an einen
       (möglicherweise unterschiedlichen) Verfolger angehängt werden oder nicht angehängt und folglich nicht auf
       Fehler  untersucht werden. Daher bedeutet »verfolgter Prozess« immer »(ein) Thread«, niemals »ein Prozess
       (mit möglicherweise mehreren Threads)«.  Ptrace-Befehle  werden  immer  an  einen  bestimmten  verfolgten
       Prozess gesandt. Der Aufruf hat folgende Form:

           ptrace(PTRACE_foo, PID, …)

       wobei PID die Thread-Kennung des zugehörigen Linux-Threads ist.

       (Beachten  Sie,  dass  auf dieser Seite ein »Prozess aus mehreren Threads« eine Thread-Gruppe bezeichnet,
       die aus Threads besteht, die mittels des clone(2)-Schalters CLONE_THREAD erzeugt wurde.)

       Ein Prozess kann eine Verfolgung mittels fork(2) starten und als Ergebnis einen Kindprozess erhalten, der
       PTRACE_TRACEME  ausführt,  was  (üblicherweise)  von  einem  execve(2)  gefolgt wird. Alternativ kann ein
       Prozess die Verfolgung eines anderen Prozesses mittels PTRACE_ATTACH oder PTRACE_SEIZE beginnen.

       Während der Prozess verfolgt wird, wird er jedesmal stoppen, wenn ein Signal gesandt wird, sogar wenn das
       Signal ignoriert wird. (Eine Ausnahme ist SIGKILL, das seine normale Wirkung erzielt.) Der Verfolger wird
       bei seinem nächsten Aufruf von waitpid(2) (oder den  zugehörigen  »wait«-Systemaufrufen)  benachrichtigt;
       dies  wird  einen  Statuswert  zurückgeben, der Informationen enthält, die den Grund angeben, weshalb der
       verfolgte Prozess stoppte. Während der verfolgte Prozess angehalten ist, kann der Verfolger  verschiedene
       Ptrace-Anfragen verwenden, um den verfolgten Prozess zu untersuchen und zu verändern. Dann veranlasst der
       Verfolger den verfolgten Prozess fortzufahren und wahlweise das  versandte  Signal  zu  ignorieren  (oder
       stattdessen sogar ein anderes Signal zu senden).

       Falls  die  Option PTRACE_O_TRACEEXEC nicht in Kraft ist, werden alle erfolgreichen Aufrufe von execve(2)
       durch den verfolgten Prozess zum Senden eines  SIGTRAP-Signals  veranlassen,  um  dem  Elternprozess  die
       Möglichkeit zu geben, die Kontrolle zu erlangen, bevor die Ausführung des neuen Programms beginnt.

       Wenn  der  Verfolger  die  Verfolgung  beendet  hat,  kann  er veranlassen, das der verfolgte Prozess mit
       PTRACE_DETACH in einem normal Modus ohne Verfolgung fortfährt.

       Der Wert des Arguments Anfrage legt die Aktion des Systemaufrufs fest:

       PTRACE_TRACEME
              zeigt an, dass dieser Prozess durch seinen Elternprozess verfolgt wird. Ein Prozess  sollte  diese
              Anfrage   wahrscheinlich   nicht   stellen,  falls  sein  Elternprozess  nicht  erwartet,  ihn  zu
              verfolgen.(PID, Adresse und Daten werden ignoriert.)

              Die PTRACE_TRACEME-Anfrage wird nur vom verfolgten Prozess  benutzt;  die  verbleibenden  Anfragen
              werden nur vom verfolgenden Prozess benutzt. In den folgenden Anfragen gibt PID die Thread-Kennung
              des verfolgten Prozesses an, der beeinflusst werden soll. Für andere Anfragen  als  PTRACE_ATTACH,
              PTRACE_SEIZE, PTRACE_INTERRUPT und PTRACE_KILL muss der verfolgte Prozess gestoppt werden.

       PTRACE_PEEKTEXT, PTRACE_PEEKDATA
              liest  ein  »word«  an der Stelle Adresse im Speicher des verfolgten Prozesses und gibt das »word«
              als Ergebnis des ptrace()-Aufrufs zurück. Linux hat  keine  separaten  Adressräume  für  Text  und
              Daten,  daher sind diese beiden Anfragen derzeit gleichwertig. (Das Argument Daten wird ignoriert,
              lesen Sie aber auch ANMERKUNGEN.)

       PTRACE_PEEKUSER
              Liest ein »word« bei Versatz Adresse im BENUTZERbereich des verfolgten Prozesses, der die Register
              und  andere  Informationen  über  den  Prozess  enthält  (siehe <sys/user.h>). Das »word« wird als
              Ergebnis  des  ptrace()-Aufrufs  zurückgegeben.  Typischerweise  muss  der   Versatz   am   »word«
              ausgerichtet  sein,  obwohl  dies  je  nach Architektur variieren kann. Lesen Sie die ANMERKUNGEN.
              (Daten wird ignoriert, lesen Sie aber auch ANMERKUNGEN.)

       PTRACE_POKETEXT, PTRACE_POKEDATA
              kopiert das »word« Daten an die Stelle Adresse im Speicher des  verfolgenden  Prozesses.  Wie  bei
              PTRACE_PEEKTEXT und PTRACE_PEEKDATA sind die beiden Anfragen derzeit gleichwertig.

       PTRACE_POKEUSER
              kopiert  das  »word« Daten an den Versatz Adresse im BENUTZERbereich des verfolgten Prozesses. Wie
              für PTRACE_PEEKUSER muss der Versatz am »word« ausgerichtet sein. Um die  Integrität  des  Kernels
              aufrecht zu erhalten, sind einige Änderungen in BENUTZERbereich nicht erlaubt.

       PTRACE_GETREGS, PTRACE_GETFPREGS
              kopiert  die  Mehrzweck- beziehungsweise Fließpunktregister des verfolgten Prozesses an die Stelle
              Daten im Verfolger. Lesen Sie <sys/user.h>, um Informationen  über  das  Format  dieser  Daten  zu
              erhalten.  (Adresse wird ignoriert.) Beachten Sie, dass auf SPARC-Systemen die Bedeutung von Daten
              und Adresse umgekehrt ist; daher wird Daten ignoriert und  die  Register  werden  an  die  Adresse
              Adresse kopiert. PTRACE_GETREGS und PTRACE_GETFPREGS sind nicht auf allen Architekturen verfügbar.

       PTRACE_GETREGSET (seit Linux 2.6.34)
              liest die Register des verfolgten Prozesses. Adresse gibt auf eine von der Architektur unabhängige
              Weise den Typ des Registers an, das gelesen werden soll.  NT_PRSTATUS  (mit  numerischem  Wert  1)
              führt  normalerweise  dazu,  dass  Allzweckregister  gelesen  werden.  Falls  die CPU zum Beispiel
              Fließkomma- und/oder Vektorregister hat, können sie durch Setzen von Adresse auf die entsprechende
              Konstante NT_foo ermittelt werden. Daten zeigt auf einen struct iovec, der den Speicherort und die
              Länge des Zielpuffers beschreibt. Bei der Rückkehr ändert der Kernel iov.len, um die  tatsächliche
              Anzahl zurückgegebener Byte anzuzeigen.

       PTRACE_SETREGS, PTRACE_SETFPREGS
              verändert  die  Mehrzweck-  beziehungsweise  Fließpunktregister  des  verfolgten Prozesses von der
              Adresse Daten im Verfolger. Wie für PTRACE_POKEUSER können einige Änderungen am  Mehrzweckregister
              verboten  sein.  (Adresse wird ignoriert.) Beachten Sie, dass auf SPARC-Systemen die Bedeutung von
              Daten und Adresse umgekehrt ist; daher wird Daten  ignoriert  und  die  Register  werden  von  der
              Adresse  Adresse  kopiert.  PTRACE_SETREGS und PTRACE_SETFPREGS sind nicht auf allen Architekturen
              verfügbar.

       PTRACE_SETREGSET (seit Linux 2.6.34)
              verändert die Register des verfolgten Prozesses. Die Bedeutung von Adresse und Daten ist analog zu
              PTRACE_GETREGSET.

       PTRACE_GETSIGINFO (seit Linux 2.3.99-pre6)
              ruft  Informationen über das Signal ab, das den Stopp verursachte. Kopiert eine siginfo_t-Struktur
              (siehe sigaction(2)) vom verfolgten Prozess an  die  Stelle  Daten  im  Verfolger.  (Adresse  wird
              ignoriert.)

       PTRACE_SETSIGINFO (seit Linux 2.3.99-pre6)
              setzt  Signalinformationen: kopiert eine siginfo_t-Struktur von der Adresse Daten vom verfolgenden
              zum verfolgten Prozess. Dies wird nur Signale  betreffen,  die  normalerweise  an  den  verfolgten
              Prozess  zugestellt  würden und vom Verfolger abgefangen wurden. Es könnte schwierig werden, diese
              normalen Signale von künstlichen Signalen zu unterscheiden,  die  von  ptrace()  selbst  generiert
              wurden. (Adresse wird ignoriert.)

       PTRACE_PEEKSIGINFO (seit Linux 3.10)
              fragt  siginfo_t-Strukturen  ab,  ohne Signale aus einer Warteschlange zu entfernen. Adresse zeigt
              auf eine ptrace_peeksiginfo_args-Struktur, die die Ordnungsposition angibt, von der  das  Kopieren
              der  Signale  starten soll sowie die Anzahl zu kopierender Signale. siginfo_t-Strukturen werden in
              den Puffer kopiert, auf den Daten verweist. Der Rückgabewert  enthält  die  Anzahl  der  kopierten
              Signale  (null  zeigt  an,  dass es an der angegebenen Ordnungsposition kein entsprechendes Signal
              gibt). Innerhalb der zurückgegebenen siginfo-Strukturen enthält  das  Feld  si_code  Informationen
              (__SI_CHLD, __SI_FAULT, etc.), die ansonsten nicht an den Anwendungsraum offengelegt werden.

           struct ptrace_peeksiginfo_args {
               u64 off;    /* Ordnungsposition in der Warteschlange, an der
                              mit dem Kopieren der Signale begonnen wird */
               u32 flags;  /* PTRACE_PEEKSIGINFO_SHARED oder 0 */
               s32 nr;     /* Anzahl zu kopierender Signale */
           };

              Derzeit  gibt  es  nur einen Schalter, PTRACE_PEEKSIGINFO_SHARED, um Signale aus der prozessweiten
              Signalwarteschlange auszugeben. Falls dieser Schalter nicht gesetzt ist, werden  Signale  von  der
              Thread-eigenen Warteschlange des angegebenen Threads gelesen.

       PTRACE_GETSIGMASK (seit Linux 3.11)
              Platzieren  Sie eine Kopie der Maske blockierter Signale (siehe sigprocmask(2)) in den Puffer, auf
              den Daten zeigt. Dies sollte ein Zeiger auf einen Puffer des  Typs  sigset_t  sein.  Das  Argument
              Adresse enthält die Größe des Puffers, auf den Daten zeigt (d.h. sizeof(sigset_t)).

       PTRACE_SETSIGMASK (seit Linux 3.11)
              ändert  die Maske blockierter Signale (siehe sigprocmask(2)) auf den Wert, der im Puffer angegeben
              wird, auf den Daten zeigt. Dies sollte ein Zeiger auf einen Puffer des  Typs  sigset_t  sein.  Das
              Argument Adresse enthält die Größe des Puffers, auf den Daten zeigt (d.h. sizeof(sigset_t)).

       PTRACE_SETOPTIONS (seit Linux 2.4.6; siehe FEHLER für Vorsichtsmaßnahmen)
              setzt  Ptrace-Optionen  von  Daten.  (Adresse wird ignoriert.) Daten wird als Bit in der Maske der
              Optionen interpretiert, die durch die folgenden Schalter angegeben wird:

              PTRACE_O_EXITKILL (seit Linux 3.8)
                     schickt an den verfolgten Prozess ein SIGKILL-Signal, falls der verfolgende Prozess beendet
                     wird.  Diese  Option  ist  für diejenigen nützlich, die Ptrace einsperren und sicherstellen
                     wollen, dass der verfolgte Prozess nie der Steuerung des verfolgenden Prozesses entkommt.

              PTRACE_O_TRACECLONE (seit Linux 2.5.46)
                     stoppt den verfolgten Prozess beim nächsten Aufruf von clone(2) und startet automatisch die
                     Verfolgung  des  neu  geklonten  Prozesses,  der mit einem SIGSTOP oder, falls PTRACE_SEIZE
                     benutzt wurde, mit PTRACE_EVENT_STOP starten wird. Ein waitpid(2) durch den Verfolger  wird
                     einen Statuswert wie diesen zurückgeben:

                       status>>8 == (SIGTRAP | (PTRACE_EVENT_CLONE<<8))

                     Die PID des neuen Prozesses kann mit PTRACE_GETEVENTMSG abgefragt werden.

                     Diese  Option  kann  nicht  in  allen Fällen clone(2)-Aufrufe abfangen. Falls der verfolgte
                     Prozess clone(2) mit dem Schalter CLONE_VFORK aufruft, wird stattdessen  PTRACE_EVENT_VFORK
                     geschickt,   wenn  PTRACE_O_TRACEVFORK  gesetzt  ist;  andernfalls  wird  PTRACE_EVENT_FORK
                     geschickt,  wenn  der  verfolgte  Prozess  clone(2)   mit   dem   auf   SIGCHLD   gesetzten
                     Beendigungssignal aufgerufen wird, falls PTRACE_O_TRACEFORK gesetzt ist.

              PTRACE_O_TRACEEXEC (seit Linux 2.5.46)
                     stoppt  den  verfolgten Prozess beim nächsten execve(2). Ein waitpid(2) durch den Verfolger
                     wird einen Statuswert wie diesen zurückgeben:

                       status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))

                     Falls der ausführende Thread kein führender Thread der Gruppe ist, wird die  Thread-Kennung
                     vor  dem  Stopp  auf die Kennung des führenden Threads der Gruppe zurückgesetzt. Seit Linux
                     3.0 kann die vorherige Thread-Kennung mit PTRACE_GETEVENTMSG abgefragt werden.

              PTRACE_O_TRACEEXIT (seit Linux 2.5.60)
                     stoppt den verfolgten Prozess beim Beenden. Ein waitpid(2) durch den Verfolger  wird  einen
                     Statuswert wie diesen zurückgeben:

                       status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))

                     Der Exit-Status des verfolgten Prozesses kann mit PTRACE_GETEVENTMSG abgefragt werden.

                     Der verfolgte Prozess wird frühzeitig während des Beendens gestoppt, wenn die Register noch
                     verfügbar sind, was es dem Verfolger ermöglicht, zu sehen, wo das Beenden veranlasst wurde,
                     wohingegen  die  normale  Benachrichtigung  über  die  Beendigung  geschickt wird, wenn der
                     Prozess das Beenden abgeschlossen hat. Auch  wenn  der  Kontext  verfügbar  ist,  kann  der
                     Verfolger das Beenden an diesem Punkt nicht mehr verhindern.

              PTRACE_O_TRACEFORK (seit Linux 2.5.46)
                     stoppt  den  verfolgten Prozess beim nächsten Aufruf von fork(2) und startet die Verfolgung
                     des neuen Prozesszweiges, der mit einem SIGSTOP oder, falls PTRACE_SEIZE benutzt wurde, mit
                     PTRACE_EVENT_STOP  starten  wird.  Ein waitpid(2) durch den Verfolger wird einen Statuswert
                     wie diesen zurückgeben:

                       status>>8 == (SIGTRAP | (PTRACE_EVENT_FORK<<8))

                     Die PID des neuen Prozesses kann mit PTRACE_GETEVENTMSG abgefragt werden.

              PTRACE_O_TRACESYSGOOD (seit Linux 2.4.6)
                     Wenn Systemaufrufe abgefangen werden, wird Bit 7 in der Signalnummer gesetzt (d.h.  SIGTRAP
                     |  0x80  geschickt).  Dies erleichtert es dem Verfolger, den Unterschied zwischen normalen,
                     abgefangenen  Signalen  und  denen,  die  durch  einen  Systemaufruf   verursacht   wurden,
                     mitzuteilen.

              PTRACE_O_TRACEVFORK (seit Linux 2.5.46)
                     stoppt den verfolgten Prozess beim nächsten Aufruf von vfork(2) und startet automatisch die
                     Verfolgung des neuen »vfork«-Prozesszweiges, der mit einem SIGSTOP oder, falls PTRACE_SEIZE
                     benutzt  wurde, mit PTRACE_EVENT_STOP starten wird. Ein waitpid(2) durch den Verfolger wird
                     einen Statuswert wie diesen zurückgeben:

                       status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK<<8))

                     Die PID des neuen Prozesses kann mit PTRACE_GETEVENTMSG abgefragt werden.

              PTRACE_O_TRACEVFORKDONE (seit Linux 2.5.60)
                     stoppt den verfolgten Prozess bei Vollendung des nächsten vfork(2).  Ein  waitpid(2)  durch
                     den Verfolger wird einen Statuswert wie diesen zurückgeben:

                       status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK_DONE<<8))

                     Die PID des neuen Prozesses kann (seit Linux 2.6.18) abgefragt werden mit

              PTRACE_O_TRACESECCOMP (seit Linux 3.5)
                     stoppt den verfolgten Prozess, wenn eine seccomp(2) SECCOMP_RET_TRACE-Regel ausgelöst wird.
                     Ein waitpid(2) durch den Verfolger wird einen Statuswert wie diesen zurückgeben:

                       status>>8 == (SIGTRAP | (PTRACE_EVENT_SECCOMP<<8))

                     Während dies  ein  PTRACE_EVENT-Stopp  auslöst,  ist  es  einem  Systemaufrufeintrittsstopp
                     ähnlich.  Für Details lesen Sie die Bemerkungen über PTRACE_EVENT_SECCOMP weiter unten. Die
                     Seccomp-Ereignisnachrichtendaten    (aus     dem     Abschnitt     SECCOMP_RET_DATA     der
                     Seccomp-Filterregel) können über PTRACE_GETEVENTMSG ermittelt werden.

              PTRACE_O_SUSPEND_SECCOMP (seit Linux 4.3)
                     setzt  den  Seccomp-Schutz des verfolgten Prozesses aus. Dies gilt unabhängig vom Modus und
                     kann verwandt werden, wenn der verfolgte Prozess noch keine Seccomp-Filter installiert hat.
                     Das   bedeutet,   dass  ein  gültiger  Anwendungsfall  darin  besteht,  den  Seccomp-Schutz
                     auszusetzen, bevor er von dem verfolgten Prozess  installiert  wird,  dann  den  verfolgten
                     Prozess die Filter installieren zu lassen und danach diesen Schalter wieder zurückzusetzen,
                     wenn die Filter wiederaufgenommen werden sollen.  Um  diese  Option  zu  setzen,  muss  der
                     verfolgende  Prozess  über  die  Capability  CAP_SYS_ADMIN  verfügen, er darf selber keinen
                     Seccomp-Schutz installiert haben und darf nicht PTRACE_O_SUSPEND_SECCOMP  auf  sich  selbst
                     setzen.

       PTRACE_GETEVENTMSG (seit Linux 2.5.46)
              fragt  eine Nachricht (als unsigned long) über das Ptrace-Ereignis, das einfach so auftrat, ab und
              platziert es an die Adresse Daten im Verfolger. Für PTRACE_EVENT_EXIT ist dies der Exit-Status des
              verfolgten  Prozesses.  Für  PTRACE_EVENT_FORK, PTRACE_EVENT_VFORK und PTRACE_EVENT_CLONE ist dies
              die PID des neuen Prozesses. Für PTRACE_EVENT_SECCOMP ist  das  SECCOMP_RET_DATA  von  seccomp(2)s
              Filter, das der ausgelösten Regel zugeordnet ist. (Adresse wird ignoriert.)

       PTRACE_CONT
              startet  den gestoppten, verfolgten Prozess erneut. Falls Daten nicht null ist, wird es als Nummer
              des Signals interpretiert, das an den verfolgten Prozess geschickt  wird;  andernfalls  wird  kein
              Signal geschickt. Dadurch kann der Verfolger zum Beispiel steuern, ob ein Signal an den verfolgten
              Prozess geschickt wird oder nicht. (Adresse wird ignoriert.)

       PTRACE_SYSCALL, PTRACE_SINGLESTEP
              startet den gestoppten,  verfolgten  Prozess  wie  für  PTRACE_CONT,  arrangiert  aber,  dass  der
              verfolgte  Prozess  beim  nächsten  Eintritt  oder  einem  Systemaufruf  beziehungsweise  nach der
              Ausführung einer einzelnen Anweisung gestoppt wird. (Der verfolgte Prozess wird auch, wie  üblich,
              über  den  Empfang  des  Signals  gestoppt.)  Aus  der Sicht des Verfolgers scheint es, als ob der
              verfolgte Prozess durch Empfang eines SIGTRAP gestoppt wurde.  Daher  gibt  es  zum  Beispiel  für
              PTRACE_SYSCALL  die  Idee, beim ersten Stopp die Argumente des Systemaufrufs zu prüfen, dann einen
              anderen PTRACE_SYSCALL zu schicken und den Rückgabewert des  Systemaufrufs  am  zweiten  Stopp  zu
              prüfen. Das Argument Daten wird wie für PTRACE_CONT behandelt. (Adresse wird ignoriert.)

       PTRACE_SET_SYSCALL (seit Linux 2.6.16)
              Wenn  im  Systemaufrufeintrittsstopp,  wird die Nummer des auszuführenden Systemaufrufs auf die im
              Argument data angegebene Nummer geändert. Das Argument  addr  wird  ignoriert.  Die  Anfrage  wird
              derzeit  nur auf Arm (und Arm64, allerdings nur für die Rückwärtskompatibilität) unterstützt, aber
              die meisten anderen Architekturen haben andere Mittel, um dies zu erreichen  (normalerweise  durch
              Änderung  des  Registers,  in  dem  der  Code aus der Anwendungsebene die Nummer des Systemaufrufs
              übergab).

       PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP (seit Linux 2.6.14)
              für PTRACE_SYSEMU beim  nächsten  Eintritt  für  den  Systemaufruf,  der  nicht  ausgeführt  wird,
              fortfahren   und  stoppen.  Siehe  die  Dokumentation  zu  Systemaufrufstopps  weiter  unten.  Für
              PTRACE_SYSEMU_SINGLESTEP das gleiche tun, aber in einem einzigen Schritt, wenn es  sich  nicht  um
              einen  Systemaufruf handelt. Dieser Aufruf wird von Programmen wie »User Mode Linux« verwandt, die
              die Systemaufrufe des verfolgten Prozesses emulieren wollen.  Das  Argument  Daten  wird  wie  für
              PTRACE_CONT  behandelt.  Das  Argument  Adresse  wird ignoriert. Diese Anfragen werden derzeit nur
              unter x86 unterstützt.

       PTRACE_LISTEN (seit Linux 3.4)
              startet den  gestoppten  verfolgten  Prozess  erneut,  verhindert  jedoch  seine  Ausführung.  Der
              resultierende  Status  ist  dem  eines  Prozesses ähnlich, der durch ein SIGSTOP (oder ein anderes
              Stoppsignal)  angehalten  wurde.  Zusätzliche   Informationen   finden   Sie   im   Unterabschnitt
              »Gruppenstopp«.  PTRACE_LISTEN  funktioniert  nur bei verfolgten Prozessen, die durch PTRACE_SEIZE
              angehängt wurden.

       PTRACE_KILL
              sendet dem verfolgten  Prozess  ein  SIGKILL,  um  ihn  zu  beenden.  (Adresse  und  Daten  werden
              ignoriert.)

              Diese  Aktion  ist  überholt;  benutzen  Sie  sie nicht! Senden Sie stattdessen ein SIGKILL direkt
              mittels kill(2) oder tgkill(2). Das Problem bei PTRACE_KILL ist, dass es verlangt, dass  sich  der
              verfolgte  Prozess in einem Signallieferstopp befindet, andernfalls funktioniert es möglicherweise
              nicht (d.h. es könnte komplett erfolgreich sein, würde aber den  verfolgten  Prozess  killen).  Im
              Gegensatz dazu hat das direkte Senden von einem SIGKILL keine derartige Beschränkung.

       PTRACE_INTERRUPT (seit Linux 3.4)
              stoppt  einen  verfolgten  Prozess. Falls der verfolgte Prozess im Kernel-Space läuft oder schläft
              und    PTRACE_SYSCALL    in    Kraft    ist,    wird    der    Systemaufruf    unterbrochen    und
              Systemaufrufbeendigungsstopp  gemeldet.  (Der  unterbrochene  Systemaufruf  wird beim Neustart des
              verfolgten Prozesses ebenfalls neu gestartet.) Falls  der  verfolgte  Prozess  bereits  durch  ein
              Signal  gestoppt  und  PTRACE_LISTEN  an  ihn  gesendet  wurde,  stoppt  der verfolgte Prozess mit
              PTRACE_EVENT_STOP und  WSTOPSIG(Status)  gibt  das  Stoppsignal  zurück.  Falls  zur  selben  Zeit
              irgendein  anderes  »ptrace-stop«  erzeugt  wird  (zum Beispiel, weil ein Signal an den verfolgten
              Prozess gesendet wird), tritt dieses »ptrace-stop« auf. Falls  nichts  von  obigem  zutrifft  (zum
              Beispiel, weil der verfolgte Prozess im Anwendungsraum läuft), stoppt er mit PTRACE_EVENT_STOP mit
              WSTOPSIG(status) == SIGTRAP. PTRACE_INTERRUPT funktioniert nur bei verfolgten Prozessen, die durch
              PTRACE_SEIZE angehängt wurden.

       PTRACE_ATTACH
              hängt  an  den  Prozess, der durch PID angegeben wird, an und lässt ihn zum verfolgten Prozess des
              aufrufenden Prozesses werden. Dem verfolgten Prozess wird ein SIGSTOP gesandt, er wird aber  nicht
              notwendigerweise durch die Vollendung dieses Aufrufs gestoppt; benutzen Sie waitpid(2), um auf das
              Stoppen des verfolgten Prozesses zu warten. Lesen Sie den Unterabschnitt »Anhängen und  Loslösen«,
              um zusätzliche Informationen zu erhalten. (Adresse und Daten werden ignoriert.)

              Berechtigungen,       ein       PTRACE_ATTACH      durchzuführen,      werden      durch      eine
              Ptrace-Zugriffsmodus-PTRACE_MODE_ATTACH_REALCREDS-Überprüfung geregelt; siehe unten.

       PTRACE_SEIZE (seit Linux 3.4)
              hängt an den zu dem in  PID  angegebenen  Prozess  an,  wodurch  er  ein  verfolgter  Prozess  des
              aufrufenden  Prozesses  wird.  Anders  als  PTRACE_ATTACH  beendet PTRACE_SEIZE den Prozess nicht.
              Gruppenstopps werden als PTRACE_EVENT_STOP berichtet und WSTOPSIG(status) liefert das Stopp-Signal
              zurück.  Automatisch  angehängte Kinder stoppen mit PTRACE_EVENT_STOP und WSTOPSIG(status) liefert
              SIGTRAP  zurück,  statt  ein  SIGSTOP  Signal  geliefert  zu  bekommen.  execve(2)  liefert   kein
              zusätzliches SIGTRAP aus. Nur ein Prozess, der PTRACE_SEIZE ist, kann die Befehle PTRACE_INTERRUPT
              und PTRACE_LISTEN akzeptieren. Das gerade beschriebene »beschlagnahmte« (engl. »seized«) Verhalten
              wird  von  Kindern  geerbt,  die  automatisch  mittels PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK und
              PTRACE_O_TRACECLONE angehängt sind. Adresse muss Null sein. Daten enthält eine Bitmaske,  die  die
              sofort zu aktivierenden Optionen enthält.

              Berechtigungen,       ein       PTRACE_SEIZE       durchzuführen,      werden      durch      eine
              Ptrace-Zugriffsmodus-PTRACE_MODE_ATTACH_REALCREDS-Überprüfung geregelt; siehe unten.

       PTRACE_SECCOMP_GET_FILTER (seit Linux 4.4)
              Diese Aktion erlaubt es dem  verfolgenden  Prozess,  die  klassischen  BPF-Filter  des  verfolgten
              Prozesses auszugeben.

              Adresse  ist  eine  Ganzzahl,  die  den Index des Filters, der ausgegeben werden soll, angibt. Der
              neuste installierte Filter hat den Index 0. Falls Adresse größer als die Anzahl der  installierten
              Filter ist, schlägt die Aktion mit dem Fehler ENOENT fehl.

              Daten  ist  entweder  ein  Zeiger  auf  ein  Feld  struct  sock_filter,  das  groß  genug ist, ein
              BPF-Programm zu speichern, oder NULL, falls das Programm nicht gespeichert werden soll.

              Im Erfolgsfall ist der Rückgabewert die Anzahl der Befehle in dem BPF-Programm. Falls  Daten  NULL
              war, dann kann dieser Rückgabewert benutzt werden, um in einem folgenden Aufruf die korrekte Größe
              des Feldes struct sock_filter zu übergeben.

              Diese Aktion schlägt mit dem Fehler  EACCES  fehl,  falls  der  Aufrufende  nicht  die  Capability
              CAP_SYS_ADMIN hat oder falls der Aufrufende in einem strikten oder Filter-Seccomp-Modus ist. Falls
              der durch Adresse referenzierte Filter kein klassischer BPF-Filter ist, schlägt die Aktion mit dem
              Fehler EMEDIUMTYPE fehl.

              Diese  Aktion  ist  verfügbar,  falls  der  Kernel  mit  den  Optionen  CONFIG_SECCOMP_FILTER  und
              CONFIG_CHECKPOINT_RESTORE konfiguriert wurde.

       PTRACE_DETACH
              startet den gestoppten, verfolgten Prozess wie für PTRACE_CONT, löst ihn aber zuerst  vom  Prozess
              ab.  Unter  Linux kann ein verfolgter Prozess auf diese Art abgelöst werden, ohne Rücksicht darauf
              zu nehmen, welche Methode zum Starten der Verfolgung benutzt wurde. (Adresse wird ignoriert.)

       PTRACE_GET_THREAD_AREA (seit Linux 2.6.0)
              Diese Aktion führt eine ähnliche Aufgabe wie get_thread_area(2) durch. Sie liest  den  TLS-Eintrag
              in  dem  GDT, dessen Index in addr gegeben ist und legt eine Kopie des Eintrags in das durch Daten
              verwiesende struct user_desc. (Im Gegensatz  wird  mit  get_thread_area(2)  die  entry_number  des
              struct user_desc ignoriert.)

       PTRACE_SET_THREAD_AREA (seit Linux 2.6.0)
              Diese  Aktion  führt eine ähnliche Aufgabe wie set_thread_area(2) durch. Sie setzt den TLS-Eintrag
              in dem GDT, dessen Index in Adresse gegeben ist, und weist ihm die in dem durch Daten  verwiesenen
              struct  user_desc  zu.  (Im  Gegensatz  zu  set_thread_area(2)  wird  die  entry_number des struct
              user_desc ignoriert; mit anderen Worten, diese Ptrace-Aktion kann nicht zur  Bereitstellung  eines
              freien TLS-Eintrags verwandt werden.)

       PTRACE_GET_SYSCALL_INFO (seit Linux 5.3)
              Ermittelt  Informationen  über den Systemaufruf, der den Stopp ausgelöst hat. Die Information wird
              in den Puffer gelegt, auf den das Argument data zeigt, das ein Zeiger auf  einen  Puffer  vom  Typ
              struct  ptrace_syscall_info  sein sollte. Das Argument addr enthält die Größe des Puffers, auf den
              das Argument data zeigt (d.h. sizeof(struct ptrace_syscall_info)). Der  Rückgabewert  enthält  die
              Anzahl von Bytes, die zum Schreiben durch den Kernel verfügbar sind. Falls die Größe der durch den
              Kernel zu schreibenden Bytes die durch das Argument addr angegebene  Größe  überschreiten  sollte,
              wird die Ausgabe abgeschnitten.

              Die Struktur ptrace_syscall_info enthält die folgenden Felder:

                  struct ptrace_syscall_info {
                      __u8 op;         /* Typ des Systemaufruf-Stopps */
                      __u32 arch;      /* AUDIT_ARCH_*-Wert; siehe seccomp(2) */
                      __u64 instruction_pointer; /* CPU-Anweisungszeiger */
                      __u64 stack_pointer;       /* CPU-Stack-Zeiger */
                      union {
                          struct {     /* op == PTRACE_SYSCALL_INFO_ENTRY */
                              __u64 nr;          /* Systemaufrufnummer */
                              __u64 args[6];     /* Systemaufrufargumente */
                          } entry;
                          struct {     /* op == PTRACE_SYSCALL_INFO_EXIT */
                              __s64 rval;        /* Systemaufruf-Rückgabewert */
                              __u8 is_error;     /* Systemaufruf-Fehlerschalter;
                                                    logisch: enthält rval einen
                                                    Fehlerwert (-ERRCODE) oder
                                                    einen nichtfehler-Rückgabewert? */
                          } exit;
                          struct {     /* op == PTRACE_SYSCALL_INFO_SECCOMP */
                              __u64 nr;          /* Systemaufrufnummer */
                              __u64 args[6];     /* Systemaufrufargumente */
                              __u32 ret_data;    /* SECCOMP_RET_DATA-Anteil
                                                    vom SECCOMP_RET_TRACE-
                                                    Rückgabewert */
                          } seccomp;
                      };
                  };

              Die   Felder   op,   arch,   instruction_pointer   und  stack_pointer  sind  für  alle  Arten  von
              Ptrace-Systemaufrufstopps definiert. Der Rest der Struktur ist eine Union; Sie sollten nur  solche
              Felder lesen, die für Ihre Art von Systemaufrufstopp durch das Feld op definiert sind.

              Das  Feld  op  enthält  einen  der  folgenden  Werte (definiert in <linux/ptrace.h>), der anzeigt,
              welcher Stopp-Typ aufgetreten und welcher Teil der Union gefüllt ist:

              PTRACE_SYSCALL_INFO_ENTRY
                     Die   Komponente   entry   der   Union   enthält   Informationen   mit   Bezug   zu   einem
                     Systemaufruf-Eintrags-Stopp.

              PTRACE_SYSCALL_INFO_EXIT
                     Die    Komponente   exit   der   Union   enthält   Informationen   mit   Bezug   zu   einem
                     Systemaufruf-Exit-Stopp.

              PTRACE_SYSCALL_INFO_SECCOMP
                     Die  Komponente  seccomp   der   Union   enthält   Informationen   mit   Bezug   zu   einem
                     PTRACE_EVENT_SECCOMP-Stopp

              PTRACE_SYSCALL_INFO_NONE
                     Keine Komponente der Union enthält relevante Informationen.

   Tod unter Ptrace
       Wenn  ein  Prozess  (der  möglicherweise aus mehreren Threads besteht) ein tötendes Signal erhält (eines,
       dessen Zuordnung auf SIG_DFL gesetzt ist und dessen Standardaktion das Töten des  Prozesses  ist)  werden
       alle Threads beendet. Verfolgte Prozesse melden ihren Tod an ihre(n) Verfolger. Die Benachrichtigung über
       dieses Ereignis wird über waitpid(2) zugestellt.

       Beachten Sie, dass das killende Signal zuerst einen Signallieferstopp (auf nur einen verfolgten  Prozess)
       verursachen wird und nur nachdem es durch den Verfolger eingespeist wurde (oder nachdem es an einen nicht
       verfolgten Thread versandt wurde), wird der Tod von dem Signal auf  alle  verfolgten  Prozesse  innerhalb
       eines  Prozesses  mit  mehreren  Threads  ausgehen.  (Der  Begriff  »Signallieferstopp«  wird nachfolgend
       erklärt.)

       SIGKILL erzeugt keinen »Signallieferstopp«. Daher kann der Verfolger es nicht unterdrücken. SIGKILL killt
       sogar  innerhalb  von  Systemaufrufen  (der Systemaufrufbeendigungsstopp wird nicht vorrangig vor dem Tod
       durch SIGKILL erzeugt). Der reine Effekt besteht darin, dass SIGKILL  den  Prozess  (all  seine  Threads)
       immer killt, sogar dann, wenn einige Threads des Prozesses verfolgt werden.

       Wenn der verfolgte Prozess _exit(2) aufruft, meldet er seinem Verfolger seinen Tod. Andere Threads werden
       nicht beeinflusst.

       Wenn irgendein Thread exit_group(2) ausführt, meldet jeder verfolgte Prozess in dessen Gruppe seinen  Tod
       an den Verfolger.

       Falls  die  Option  PTRACE_O_TRACEEXIT  aktiv  ist,  wird  PTRACE_EVENT_EXIT  vor  dem  tatsächlichen Tod
       auftreten. Dies wird angewandt, um mittels exit(2), exit_group(2) und Todessignalen (ausgenommen SIGKILL,
       abhängig  von  der Kernel-Version, siehe FEHLER unten) zu beenden und wenn Threads bei execve(2) in einem
       Prozess mit mehreren Threads zerrissen werden.

       Der Verfolger kann nicht abschätzen, ob der von Ptrace  gestoppte  Prozess  existiert.  Es  gibt  mehrere
       Szenarien, in denen der verfolgte Prozess sterben kann, während er gestoppt ist (wie SIGKILL). Daher muss
       der Verfolger vorbereitet werden, bei allen Ptrace-Aktionen einen ESRCH-Fehler zu handhaben. Leider  wird
       der  gleiche  Fehler zurückgegeben, falls der verfolgte Prozess existiert, aber nicht von Ptrace gestoppt
       wurde (für Befehle, die einen gestoppten, verfolgten Prozess erfordern) oder falls  er  nicht  durch  den
       Prozess  verfolgt  wird,  der  den  Ptrace-Aufruf  abschickte.  Der Verfolger muss den Überblick über den
       »laufend«-/»gestoppt«-Status des verfolgten Prozesses behalten und ESRCH nur dann als »verfolgter Prozess
       starb unerwartet« interpretieren, falls er weiß, dass der verfolgte Prozess beobachtet wurde, um in einen
       Ptrace-Stopp einzutreten. Beachten Sie, dass es keine Garantie gibt,  dass  waitpid(WNOHANG)  zuverlässig
       den   Todesstatus   des   verfolgten   Prozesses  meldet,  falls  eine  Ptrace-Aktion  ESRCH  zurückgibt.
       waitpid(WNOHANG) könnte stattdessen 0 zurückgeben. In anderen Worten kann es  sein,  dass  der  verfolgte
       Prozess »noch nicht vollständig tot« ist, aber bereits Ptrace-Anfragen ablehnt.

       Der  Verfolger  kann  nicht  abschätzen,  ob  der  verfolgte  Prozess  immer  sein Leben durch Melden von
       WIFEXITED(status) oder WIFSIGNALED(status) aushaucht. Es gibt Fälle, in denen dies nicht geschieht. Falls
       ein  Thread,  der  nicht  führender  Thread  der  Thread-Gruppe ist, zum Beispiel ein execve(2) ausführt,
       verschwindet er; seine PID wird nie wieder gesehen und alle nachfolgenden Ptrace-Stopps werden unter  der
       PID des führenden Threads der Thread-Gruppe gemeldet.

   Gestoppt-Status
       Ein  verfolgter Prozess kann zwei Status haben: laufend oder gestoppt. Für die Zwecke von Ptrace wird ein
       durch einen Systemaufruf (wie read(2), pause(2), etc.) blockierter verfolgter Prozess dennoch als laufend
       betrachtet,  sogar,  wenn  der  verfolgte Prozess für lange Zeit blockiert ist. Der Status des verfolgten
       Prozesses nach PTRACE_LISTEN ist eine Grauzone:  Er  ist  nicht  in  einem  Ptrace-Stopp  (Ptrace-Befehle
       funktionieren nicht bei ihm und er wird waitpid(2)-Benachrichtigungen übermitteln), aber er kann auch als
       »gestoppt« angesehen werden, da er keine Anweisungen ausführt (ist nicht eingeplant)  und  falls  er  vor
       PTRACE_LISTEN in einem Gruppenstopp war, wird er nicht auf Signale antworten, bis er SIGCONT empfängt.

       Es  gibt  viele  Arten  von Status, wenn ein verfolgter Prozess gestoppt wurde und in Ptrace-Diskussionen
       werden sie oft durcheinandergebracht. Daher ist es wichtig, präzise Begriffe zu verwenden.

       In  dieser  Handbuchseite  wird  jeder  Gestoppt-Status,  in  dem  der  verfolgte  Prozess  bereit   ist,
       Ptrace-Befehle  vom  Verfolger  zu  akzeptieren,  Ptrace-Stopp  genannt.  Ptrace-Stopps  können weiter in
       Signallieferstopp, Gruppenstopp, PTRACE_EVENT stops und  so  fort  unterteilt  werden.  Diese  gestoppten
       Status werden nachfolgend im Detail beschrieben.

       Wenn der laufende, verfolgte Prozess in Ptrace-Stopp eintritt, benachrichtigt er seinen Verfolger mittels
       waitpid(2) (oder einem anderen der »wait«-Systemaufrufe). Meistens geht diese  Handbuchseite  davon  aus,
       dass der Verfolger wartet mit:

           PID = waitpid(PID_ODER_Minus1, &status, __WALL);

       Mit  Ptrace-Stopp  angehaltene,  verfolgte  Prozesse  werden  als  Rückgaben  mit  PID  größer  als 0 und
       »WIFSTOPPED(status) true« gemeldet.

       Der Schalter __WALL enthält nicht die Schalter WSTOPPED und WEXITED, impliziert aber ihre Funktionalität.

       Es wird nicht empfohlen, den Schalter WCONTINUED zu setzen, wenn waitpid(2) aufgerufen wird:  Der  Status
       »continued«  gilt  pro  Prozess  und  ihn  zu  verbrauchen,  kann den echten Elternprozess des verfolgten
       Prozesses verwirren.

       Die Benutzung  des  Schalters  WNOHANG  könnte  waitpid(2)  veranlassen,  0  zurückzugeben  (»noch  keine
       Warteergebnisse  verfügbar«),  sogar  dann, wenn der Verfolger weiß, dass dort eine Benachrichtigung sein
       soll. Beispiel:

           errno = 0;
           ptrace(PTRACE_CONT, pid, 0L, 0L);
           if (errno == ESRCH) {
               /* verfolgter Prozess ist tot */
               r = waitpid(tracee, &status, __WALL | WNOHANG);
               /* r kann hier immer noch 0 sein! */
           }

       Die folgenden Arten von Ptrace-Stopps existieren: Signallieferstopps, Gruppenstopps,  PTRACE_EVENT-Stopps
       und  Systemaufrufstopps.  Sie  alle  werden  von  waitpid(2)  mit »WIFSTOPPED(status) true« gemeldet. Sie
       könnten durch Untersuchen des Wertes status>>8 unterschieden werden und, falls es eine Unklarheit im Wert
       gibt,  durch  Abfragen  von  PTRACE_GETSIGINFO. (Hinweis: Das Makro WSTOPSIG(status) kann nicht für diese
       Untersuchung verwandt werden, da es den Wert (status>>8) & 0xff zurückgibt.)

   Signallieferstopp
       Wenn ein Prozess (möglicherweise mit mehreren Threads) ein  Signal  außer  SIGKILL  empfängt,  wählt  der
       Kernel  einen  beliebigen  Thread  aus,  der das Signal handhabt. (Falls das Signal mit tgkill(2) erzeugt
       wurde, kann der Ziel-Thread explizit durch den Aufrufenden  ausgewählt  werden.)  Falls  der  ausgewählte
       Thread verfolgt wird, tritt er in einen Signallieferstopp ein. An diesem Punkt wird das Signal noch nicht
       an den Prozess zugestellt und kann durch den Verfolger unterdrückt werden. Falls der Verfolger das Signal
       nicht  unterdrückt,  übergibt  er  das  Signal  bei der nächsten Ptrace-Neustartanfrage an den verfolgten
       Prozess. Dieser zweite Schritt  der  Signalzustellung  wird  in  dieser  Handbuchseite  Signaleinspeisung
       genannt.  Beachten  Sie,  dass, falls das Signal blockiert ist, der Signallieferstopp nicht auftritt, bis
       die Blockade des Signals aufgehoben wurde, mit der üblichen Ausnahme, dass SIGSTOP nicht blockiert werden
       kann.

       Der  Signallieferstopp  wird  vom  Verfolger  als waitpid(2) beobachtet und kehrt mit »WIFSTOPPED(status)
       true« mit dem Signal zurück, das von WSTOPSIG(status) zurückgegeben wurde. Falls das Signal SIGTRAP  ist,
       könnte  dies  eine  andere  Art  eines  Ptrace-Stopps  sein;  Einzelheiten  finden Sie in den Abschnitten
       »Systemaufrufstopps« und »execve« unterhalb. Falls WSTOPSIG(status)  ein  stoppendes  Signal  zurückgibt,
       könnte dies ein Gruppenstopp sein; siehe unten.

   Signaleinspeisung und -unterdrückung
       Nachdem  der  Signallieferstopp durch den Verfolger beobachtet wurde, sollte der Verfolger den verfolgten
       Prozess mit dem Aufruf

           ptrace(PTRACE_restart, PID, 0, Signal)

       neu starten, wobei PTRACE_restart einer der neu startenden Ptrace-Anfragen ist. Falls Signal 0 ist,  wird
       das  Signal  nicht zugestellt. Andernfalls wird das Signal Signal zugestellt. Diese Aktion wird in dieser
       Handbuchseite Signaleinspeisung genannt, um sie vom Signallieferstopp zu unterscheiden.

       Der Signalwert kann sich vom Wert WSTOPSIG(status) unterschieden: Der Verfolger  kann  veranlassen,  dass
       ein anderes Signal eingespeist wird.

       Beachten   Sie,  dass  ein  unterdrücktes  Signal  immer  noch  Systemaufrufe  verursacht,  um  vorzeitig
       zurückzukehren. In diesem Fall werden Systemaufrufe neu gestartet:  Der  Verfolger  wird  den  verfolgten
       Prozess   beobachten,   um  den  unterbrochenen  Systemaufruf  neu  auszuführen  (oder  den  Systemaufruf
       restart_syscall(2) für wenige  Systemaufrufe,  die  unterschiedliche  Mechanismen  zum  erneuten  Starten
       verwenden), falls der Verfolger PTRACE_SYSCALL benutzt. Sogar Systemaufrufe (wie poll(2)), die nach einem
       Signal nicht mehr neu startbar sind, werden nach dem Unterdrücken des Signals neu  gestartet  werden.  Es
       existieren  jedoch  einige  Kernelfehler,  die  zum  Fehlschlagen einiger Systemaufrufe mit EINTR führen,
       sogar, wenn kein beobachtbares Signal in den verfolgten Prozess eingespeist wurde.

       Es wird nicht garantiert, dass beim Neustarten von Ptrace-Befehlen,  die  in  anderen  Ptrace-Stopps  als
       Signallieferstopps  angestoßen  wurden,ein  Signal eingespeist wird, nicht einmal, wenn Signal nicht Null
       ist.  Es  wird  kein  Fehler  gemeldet;  ein  Signal  ungleich  Null  könnte  einfach  ignoriert  werden.
       Ptrace-Benutzer  sollten  nicht  versuchen,  auf  diese  Art »ein neues Signal zu erzeugen«: Benutzen Sie
       stattdessen tgkill(2).

       Die Tatsache, dass  Signaleinspeisungsanfragen  beim  erneuten  Starten  des  verfolgten  Prozesses  nach
       Ptrace-Stopps,  die  keine Signallieferstopps sind, ignoriert werden können, ist ein Grund für Verwirrung
       bei Ptrace-Benutzern. Ein typisches Szenario  ist,  dass  der  Verfolger  Gruppenstopps  beobachtet,  sie
       fälschlicherweise für Signallieferstopps hält und den verfolgen Prozess mit

           ptrace(PTRACE_restart, PID, 0, Stoppsignal)

       neu  startet  mit der Absicht Stoppsignal einzuspeisen, Stoppsignal aber ignoriert wird und der verfolgte
       Prozess weiter läuft.

       Das Signal SIGCONT hat einen Seiteneffekt, dass es einen Prozess im  Gruppenstopp  (alle  Threads  davon)
       aufweckt. Dieser Seiteneffekt tritt vor dem Signallieferstopp auf. Der Verfolger kann diesen Seiteneffekt
       nicht  unterdrücken  (er  kann  nur  Signaleinspeisung  unterdrücken,  was  nur  dazu  führt,  dass   die
       SIGCONT-Handhabung  nicht im verfolgten Prozess ausgeführt wird, falls eine solche Handhabung installiert
       ist). Tatsächlich könnte dem Aufwecken aus den Gruppenstopp ein Signallieferstopp für andere Signale  als
       SIGCONT  folgen,  falls sie ausstehen, wenn SIGCONT gesandt wurde. In anderen Worten könnte es sein, dass
       SIGCONT nicht das erste durch den Verfolger beobachtete Signal ist, nachdem es gesandt wurde.

       Stoppen von Signalen führt dazu, das ein Prozess (alle Threads davon)  in  einen  Gruppenstopp  eintritt.
       Dieser  Seiteneffekt  tritt nach der Signaleinspeisung auf und kann daher durch den Verfolger unterdrückt
       werden.

       In Linux 2.4 und älter kann das Signal SIGSTOP nicht eingespeist werden.

       PTRACE_GETSIGINFO kann benutzt werden, um eine siginfo_t-Struktur zu erhalten, die dem  gesandten  Signal
       entspricht.  PTRACE_SETSIGINFO  kann  benutzt werden, um es zu verändern. Falls PTRACE_SETSIGINFO benutzt
       wurde, um siginfo_t zu verändern, müssen das Feld  si_signo  und  der  Parameter  Signal  im  Befehl  zum
       Neustart übereinstimmen, andernfalls ist das Ergebnis undefiniert.

   Gruppenstopp
       Wenn  ein Prozess (der möglicherweise aus mehreren Threads besteht) ein Stoppsignal empfängt, werden alle
       Threads gestoppt. Falls einige Threads verfolgt werden, treten sie in eine  Thread-Gruppe  ein.  Beachten
       Sie,  dass  das  Stoppsignal  zuerst  einen  Signallieferstopp  verursachen  wird (nur auf den verfolgten
       Prozess) und nur, nachdem es durch den Verfolger eingespeist wurde  (oder  nachdem  es  an  einen  Thread
       geschickt  wurde,  der nicht verfolgt wird), wird der Gruppenstopp auf alle verfolgten Prozesse innerhalb
       eines Prozesses aus mehreren Threads eingeleitet.  Wie  üblich  meldet  jeder  verfolgte  Prozess  seinen
       Gruppenstopp separat an den entsprechenden Verfolger.

       Der Gruppenstopp wird vom Verfolger als waitpid(2) beobachtet und kehrt mit »WIFSTOPPED(status) true« mit
       dem Stoppsignal zurück, das über WSTOPSIG(status) verfügbar  ist.  Dasselbe  Ergebnis  wird  von  einigen
       anderen  Klassen  von  Ptrace-Stopps  zurückgegeben,  daher  ist die empfohlene Vorgehensweise, folgenden
       Aufruf zu tätigen:

           ptrace(PTRACE_GETSIGINFO, PID, 0, &siginfo)

       Der Aufruf kann vermieden werden, falls das Signal nicht SIGSTOP, SIGTSTP, SIGTTIN oder SIGTTOU ist.  Nur
       diese  vier Signale sind Stoppsignale. Falls der Verfolger etwas anderes sieht, kann es kein Gruppenstopp
       sein. Andernfalls benötigt der Verfolger den Aufruf PTRACE_GETSIGINFO. Falls PTRACE_GETSIGINFO mit EINVAL
       fehlschlägt, ist es definitiv ein Gruppenstopp. (Andere Fehlerkodes wie ESRCH (»kein derartiger Prozess«)
       sind möglich, falls ein SIGKILL den verfolgten Prozess gekillt hat.

       Falls  ein  verfolgter  Prozess  mittels  PTRACE_SEIZE  angehängt  wurde,  wird  ein  Gruppenstopp  durch
       PTRACE_EVENT_STOP  angezeigt:  Status>>16  ==  PTRACE_EVENT_STOP.  Dies  ermöglicht,  einen  Gruppenstopp
       festzustellen, ohne dass ein zusätzlicher PTRACE_GETSIGINFO-Aufruf erforderlich ist.

       Ab Linux 2.6.38 wird der verfolgte  Prozess,  nachdem  der  Verfolger  den  Ptrace-Stopp  des  verfolgten
       Prozesses  sieht  und bis er neu startet oder ihn killt, nicht laufen und keine Benachrichtigungen an den
       Verfolger senden (außer dem Tod durch SIGKILL),  nicht  einmal,  wenn  der  Verfolger  in  einen  anderen
       waitpid(2)-Aufruf gelangt.

       Das  im  vorhergehenden Absatz beschriebene Verhalten verursacht ein Problem bei transparenter Behandlung
       von Stoppsignalen. Falls der Verfolger den verfolgten Prozess nach einem Gruppenstopp neu  startet,  wird
       das  Stoppsignal  effektiv  ignoriert  – der verfolgte Prozess bleibt nicht gestoppt, er läuft. Falls der
       Verfolger den verfolgten Prozess neu startet,  bevor  er  in  das  nächste  waitpid(2)  eintritt,  werden
       zukünftige   SIGCONT-Signale  nicht  an  den  Verfolger  gemeldet.  Dies  würde  dazu  führen,  dass  die
       SIGCONT-Signale keine Auswirkungen auf den verfolgten Prozess haben.

       Seit Linux 3.4  gibt  es  eine  Methode,  die  dieses  Problem  bewältigt:  Statt  PTRACE_CONT  kann  ein
       PTRACE_LISTEN-Befehl zum Neustart eines verfolgten Prozesses auf eine Weise benutzt werden, die ihn nicht
       ausführt, aber auf ein neues Ereignis wartet, das er über waitpid(2) melden kann, wenn  er  zum  Beispiel
       mit SIGCONT neu gestartet wird.

   PTRACE_EVENT-Stopps
       Falls  der  Verfolger  PTRACE_O_TRACE_*-Optionen setzt, wird der verfolgte Prozess in PTRACE_EVENT-Stopps
       genannte Stopps gelangen.

       PTRACE_EVENT-Stopps werden durch den Verfolger als waitpid(2) beobachtet, kehren  mit  WIFSTOPPED(status)
       zurück  und  WSTOPSIG(status)  gibt  SIGTRAP  zurück  (oder  für PTRACE_EVENT_STOP: gibt das Stopp-Signal
       zurück, falls der verfolgte Prozess in einem Gruppen-Stopp ist). Es wird  ein  zusätzliches  Bit  in  das
       höhere Bit des Status (Datentyp Word) gesetzt: Der Wert status>>8 wird wie folgt sein:

           ((PTRACE_EVENT_foo<<8) | SIGTRAP).

       Es gibt die folgenden Ereignisse:

       PTRACE_EVENT_VFORK
              stoppt  vor  dem  Zurückkehren  von  vfork(2) oder clone(2) mit dem Schalter CLONE_VFORK. Wenn der
              verfolgte Prozess nach diesem Stopp fortgeführt  wird,  wird  er  auf  das  Beenden/Ausführen  des
              Kindprozesses  warten,  bevor  er  mit seiner Ausführung fortfährt (in anderen Worten, das übliche
              Verhalten auf vfork(2)).

       PTRACE_EVENT_FORK
              stoppt  vor  dem  Zurückkehren  von  fork(2)  oder  clone(2)  mit  dem   auf   SIGCHLD   gesetzten
              Beendigungssignal.

       PTRACE_EVENT_CLONE
              stoppt vor dem Zurückkehren von clone(2).

       PTRACE_EVENT_VFORK_DONE
              stoppt  vor dem Zurückkehren von vfork(2) oder clone(2) mit dem Schalter CLONE_VFORK, aber nachdem
              die Blockade dieses verfolgten Prozesses durch Beenden oder Ausführung aufgehoben wurde.

       Für alle vier oben beschriebenen Stopps tritt der  Stopp  im  Elternprozess  auf  (d.h.  im  verfolgenden
       Prozess),  nicht  im  neu  erstellten  Thread. PTRACE_GETEVENTMSG kann benutzt werden, um die Kennung des
       neuen Threads zu erhalten.

       PTRACE_EVENT_EXEC
              stoppt vor dem Zurückkehren von execve(2). Ab Linux 3.0,  gibt  PTRACE_GETEVENTMSG  die  vorherige
              Thread-Kennung zurück.

       PTRACE_EVENT_EXIT
              stoppt  vor  dem  Beenden  (einschließlich des Todes aus exit_group(2)), dem Signaltod oder endet,
              verursacht durch execve(2), in einem Prozess aus mehreren  Threads.  PTRACE_GETEVENTMSG  gibt  den
              Exit-Status zurück. Register können untersucht werden (solange nicht »wirklich« beendet wird). Der
              verfolgte Prozess ist immer noch lebendig; er benötigt zum Fertigstellen des Beendens  PTRACE_CONT
              oder PTRACE_DETACH.

       PTRACE_EVENT_STOP
              Stopp,  der  durch  einen  PTRACE_INTERRUPT-Befehl,  einen  Gruppenstopp oder ein »ptrace-stop« zu
              Beginn veranlasst wurde, wenn ein neuer Kindprozess angehängt  wird  (nur  beim  Anhängen  mittels
              PTRACE_SEIZE).

       PTRACE_EVENT_SECCOMP
              Stopp,  der  durch  eine  seccomp(2)-Regel  durch  den  Eintritt des verfolgten Prozesses in einen
              Systemaufruf  ausgelöst  wird,  wenn  PTRACE_O_TRACESECCOMP  vom  Verfolger  gesetzt   wird.   Die
              Seccomp-Ereignisdaten   (von   dem   Anteil   SECCOMP_RET_DATA   der   Filterregel)  können  durch
              PTRACE_GETEVENTMSG ermittelt  werden.  Die  Semantik  dieses  Stopps  werden  in  einem  separaten
              Abschnitt weiter unten beschrieben.

       PTRACE_GETSIGINFO   auf   PTRACE_EVENT-Stopps   gibt  SIGTRAP  in  si_signo  zurück,  wobei  si_code  auf
       (event<<8) | SIGTRAP gesetzt ist.

   Systemaufrufstopps
       Falls der verfolgte Prozess durch PTRACE_SYSCALL  oder  PTRACE_SYSEMU  neu  gestartet  wurde,  gerät  der
       verfolgte  Prozess  in einen Systemaufrufeintrittsstopp kurz vor dem Eintritt in irgendeinen Systemaufruf
       (der nicht ausgeführt wird, falls der Neustart PTRACE_SYSEMU verwandte, unabhängig von allen  Änderungen,
       die  zu  diesem  Zeitpunkt an den Registern vorgenommen wurden oder wie der verfolgte Prozess nach diesem
       Stopp neu gestartet wird). Unabhängig davon, welche Methode den  Systemaufrufeintrittsstopp  verursachte,
       falls der Verfolger den verfolgten Prozess mit PTRACE_SYSCALL neu startet, gerät der verfolgte Prozess in
       einen Systemaufrufbeendigungsstopp, wenn der Systemaufruf beendet ist oder  falls  er  durch  ein  Signal
       unterbrochen  wurde.  (Sprich,  der  Signallieferstopp  tritt nie zwischen Systemaufrufeintrittsstopp und
       Systemaufrufbeendigungsstopp auf; er findet  nach  dem  Systemaufrufbeendigungsstopp  statt.)  Falls  der
       verfolgte  Prozess  mittels  irgendeiner anderen Methode fortgesetzt wird (einschließlich PTRACE_SYSEMU),
       erfolgt kein Systemaufrufbeendigungsstop. Beachten Sie, dass alle Erwähnungen von  PTRACE_SYSEMU  genauso
       auf PTRACE_SYSEMU_SINGLESTEP zutreffen.

       Selbst  falls  der verfolgte Prozess mittels PTRACE_SYSCALL fortgesetzt wird, wird nicht garantiert, dass
       der nächste Stopp ein  Systemaufrufbeendigungsstopp  sein  wird.  Andere  Möglichkeiten  sind,  dass  der
       verfolgte Prozess in einem PTRACE_EVENT-Stopp (einschließlich Seccomp-Stopp) stoppen könnte, endet (falls
       er in _exit(2) oder exit_group(2) eintritt), durch SIGKILL gekillt wird oder leise stirbt (falls  er  die
       Thread-Gruppe  anführt,  kommt  das  execve(2)  in einem anderen Thread vor und der Thread wird nicht vom
       selben Verfolger verfolgt; diese Situation wird später besprochen).

       Systemaufrufeintrittsstopp  und  Systemaufrufbeendigungsstopp  werden  vom   Verfolger   als   waitpid(2)
       beobachtet,  kehren  mit »WIFSTOPPED(status) true« zurück und WSTOPSIG(status) gibt SIGTRAP zurück. Falls
       die Option PTRACE_O_TRACESYSGOOD durch den  Verfolger  gesetzt  wurde,  wird  WSTOPSIG(status)  den  Wert
       (SIGTRAP | 0x80) zurückgeben.

       Systemaufrufstopps  können von Signallieferstopps mit SIGTRAP durch Abfrage von PTRACE_GETSIGINFO für die
       folgenden Fälle unterschieden werden:

       si_code <= 0
              SIGTRAP wurde mit einem Ergebnis  einer  Anwendungsraumaktion,  zum  Beispiel  einem  Systemaufruf
              ((tgkill(2),   kill(2),  sigqueue(3),  etc.),  Ablauf  eines  POSIX-Timers,  Statusänderung  einer
              POSIX-Nachrichtenwarteschlange oder Vervollständigung einer asynchronen E/A-Anfrage geliefert.

       si_code == SI_KERNEL (0x80)
              SIGTRAP wurde vom Kernel gesandt.

       si_code == SIGTRAP or si_code == (SIGTRAP|0x80)
              Dies ist ein Systemaufrufstopp.

       Systemaufrufstopps kommen  jedoch  sehr  oft  vor  (zweimal  pro  Systemaufruf)  und  das  Ausführen  von
       PTRACE_GETSIGINFO für jeden Systemaufrufstopp könnte etwas aufwendig sein.

       Einige  Architekturen  erlauben,  die Fälle durch Untersuchen der Register zu unterscheiden. Zum Beispiel
       auf x86, rax == -ENOSYS im Systemaufrufeintrittsstopp. Da SIGTRAP (wie jedes andere  Signal)  immer  nach
       dem  Systemaufrufbeendigungsstopp  auftritt  und  rax  an diesem Punkt fast nie ENOSYS enthält, sieht das
       SIGTRAP aus wie ein »Systemaufrufstopp, der kein Systemaufrufeintrittsstopp ist«; in anderen  Worten,  er
       sieht  aus wie ein »herrenloser Systemaufrufbeendigungsstopp« und kann auf diese Art erkannt werden. Aber
       eine solche Erkennung ist fragil und wird am besten vermieden.

       Die Benutzung der Option PTRACE_O_TRACESYSGOOD ist die  empfohlene  Methode,  um  Systemaufrufstopps  von
       anderen  Arten der Ptrace-Stopps zu unterscheiden, da sie zuverlässig ist und sich keine Leistungseinbuße
       zuzieht.

       Systemaufrufeintrittsstopp und Systemaufrufbeendigungsstopp sind für den Verfolger nicht  voneinander  zu
       unterscheiden. Der Verfolger muss den Überblick über die Abfolge der Ptrace-Stopps behalten, um nicht den
       Systemaufrufeintrittsstopp  fälschlicherweise  als   Systemaufrufbeendigungsstopp   oder   umgekehrt   zu
       interpretieren.     Im     Allgemeinen     folgt     diesem    Systemaufrufeintrittsstopp    immer    ein
       Systemaufrufbeendigungsstopp, PTRACE_EVENT-Stopp oder der Tod des verfolgten Prozesses; dazwischen können
       keine  anderen  Arten  von  Ptrace-Stopps  auftreten. Beachten Sie allerdings, dass Seccomp-Stopps (siehe
       unten) Systemaufrufbeendigungsstopps ohne vorhergehende Systemaufrufeintrittsstopps  hervorrufen  können.
       Falls   Seccomp   verwandt   wird,   muss   Sorgfalt  eingesetzt  werden,  um  solche  Stopps  nicht  als
       Systemaufrufeintrittsstopps misszuinterpretieren.

       Falls der  Verfolger  nach  dem  Systemaufrufeintrittsstopp  einen  anderen  Befehl  zum  Neustarten  als
       PTRACE_SYSCALL verwendet, wird der Systemaufrufbeendigungsstopp nicht erzeugt.

       PTRACE_GETSIGINFO  auf Systemaufrufstopps gibt SIGTRAP in si_signo zurück, wobei si_code auf SIGTRAP oder
       (SIGTRAP|0x80) gesetzt ist.

   PTRACE_EVENT_SECCOMP-Stopps (Linux 3.5 bis 4.7)
       Das  Verhalten  des  PTRACE_EVENT_SECCOMP-Stopps  und  seiner  Wechselwirkung  mit  anderen   Arten   von
       Ptrace-Stopps  hat sich zwischen Kernel-Versionen geändert. Hier wird das Verhalten von seiner Einführung
       bis Linux 4.7 (einschließlich) beschrieben. Das Verhalten in neueren  Kernelversionen  wird  im  nächsten
       Abschnitt beschrieben.

       Ein  PTRACE_EVENT_SECCOMP-Stopp erfolgt, wann immer eine SECCOMP_RET_TRACE-Regel ausgelöst wird. Dies ist
       von der Methode, die zum Neustart des  Systemaufrufes  verwandt  wurde,  unabhängig.  Insbesondere  läuft
       Seccomp  immer  noch,  selbst  falls  der verfolgte Prozess mittels PTRACE_SYSEMU neu gestartet wurde und
       dieser Systemaufruf wird bedingungslos übersprungen.

       Neustarts aus diesem Stopp verhalten sich so, als  ob  der  Stopp  direkt  vor  dem  in  Frage  stehenden
       Systemaufruf  stattgefunden  hätte.  Insbesondere  werden  sowohl  PTRACE_SYSCALL  als auch PTRACE_SYSEMU
       normalerweise  einen  folgenden  Systemaufrufeintrittsstopp   auslösen.   Falls   allerdings   nach   dem
       PTRACE_EVENT_SECCOMP die Systemaufrufnummer negativ ist, werden sowohl der Systemaufrufeintrittsstopp als
       auch der Systemaufruf selbst übersprungen. Das bedeutet,  dass  falls  die  Systemaufrufnummer  nach  dem
       PTRACE_EVENT_SECCOMP negativ ist und der verfolgte Prozess mittels PTRACE_SYSCALL neu gestartet wird, der
       nächste  beobachtete   Stopp   ein   Systemaufrufbeendigungsstopp   statt   des   vielleicht   erwarteten
       Systemaufrufeintrittsstopps sein wird.

   PTRACE_EVENT_SECCOMP-Stopps (seit Linux 4.8)
       Beginnend  mit  Linux  4.8  wurde  der  Stopp  PTRACE_EVENT_SECCOMP  neu  geordnet,  so  dass er zwischen
       Systemaufrufeintrittsstopp und Systemaufrufbeendigungsstopp auftritt. Beachten Sie,  dass  Seccomp  nicht
       länger  ausgeführt  wird  (und  kein PTRACE_EVENT_SECCOMP berichtet wird) falls der Systemaufruf aufgrund
       PTRACE_SYSEMU übersprungen wird.

       Funktional arbeitet ein  PTRACE_EVENT_SECCOMP-Stopp  vergleichbar  mit  einem  Systemaufrufeintrittsstopp
       (d.h.  Fortsetzungen  mittels  PTRACE_SYSCALL  werden  einen  Systemaufrufbeendigungsstopp  auslösen, die
       Systemaufrufnummer könnte sich ändern und alle anderen veränderten Register sind im gleich auszuführenden
       Systemaufruf  ebenfalls  sichtbar). Beachten Sie, dass es einen vorhergehenden Systemaufrufeintrittsstopp
       gegeben haben kann, aber nicht muss.

       Nach einem Stopp PTRACE_EVENT_SECCOMP wird Seccomp mit einer Regel SECCOMP_RET_TRACE,  die  identisch  zu
       einer  SECCOMP_RET_ALLOW funktioniert, erneut ausgeführt. Insbesondere bedeutet dies, dass falls Register
       nicht während des Stopps PTRACE_EVENT_SECCOMP verändert wurden, der Systemaufruf dann erlaubt wird.

   PTRACE_SINGLESTEP-Stopps
       [Einzelheiten dieser Arten von Stopps sind noch nicht dokumentiert.]

   Benachrichtigende und neustartende Ptrace-Befehle
       Die meisten Ptrace-Befehle (alle außer PTRACE_ATTACH, PTRACE_SEIZE, PTRACE_TRACEME, PTRACE_INTERRUPT  und
       PTRACE_KILL)  erfordern,  dass der verfolgte Prozess in einem Ptrace-Stopp ist, andernfalls scheitern sie
       mit ESRCH.

       Wenn der verfolgte Prozess im Ptrace-Stopp ist, kann der Verfolger Daten des verfolgten Prozesses mittels
       benachrichtigenden  Befehlen lesen und schreiben. Diese Befehle belassen den verfolgten Prozess im Status
       Ptrace-gestoppt:

           ptrace(PTRACE_PEEKTEXT/PEEKDATA/PEEKUSER, PID, Adresse, 0);
           ptrace(PTRACE_POKETEXT/POKEDATA/POKEUSER, PID, Adresse, long_val);
           ptrace(PTRACE_GETREGS/GETFPREGS, PID, 0, &struct);
           ptrace(PTRACE_SETREGS/SETFPREGS, PID, 0, &struct);
           ptrace(PTRACE_GETREGSET, PID, NT_foo, &iov);
           ptrace(PTRACE_SETREGSET, PID, NT_foo, &iov);
           ptrace(PTRACE_GETSIGINFO, PID, 0, &siginfo);
           ptrace(PTRACE_SETSIGINFO, PID, 0, &siginfo);
           ptrace(PTRACE_GETEVENTMSG, PID, 0, &long_var);
           ptrace(PTRACE_SETOPTIONS, PID, 0, PTRACE_O_flags);

       Beachten Sie, dass einige Fehler nicht gemeldet wurden. Das Setzen des Informationssignals (siginfo)  hat
       zum  Beispiel  in  einigen  Ptrace-Stopps  möglicherweise  keine  Auswirkungen,  der  Aufruf  kann jedoch
       erfolgreich sein  (0  zurückgeben  und  errno  nicht  setzen);  Abfragen  von  PTRACE_GETEVENTMSG  könnte
       erfolgreich   sein  und  einen  zufälligen  Wert  zurückgeben,  falls  der  aktuelle  Ptrace-Stopp  nicht
       dokumentiert ist, um eine aussagekräftige Ereignisnachricht zurückzugeben.

       Der Aufruf

           ptrace(PTRACE_SETOPTIONS, PID, 0, PTRACE_O_flags);

       beeinflusst einen verfolgten Prozess. Die aktuellen Schalter des  verfolgten  Prozesses  werden  ersetzt.
       Schalter   werden   geerbt   durch   neu  erzeugte  Prozesse  und  »automatisch  angehängt«  über  aktive
       PTRACE_O_TRACEFORK-, PTRACE_O_TRACEVFORK- oder PTRACE_O_TRACECLONE-Optionen.

       Eine weitere Gruppe von Befehlen lässt die per Ptrace gestoppten, verfolgten Prozesse laufen.  Sie  haben
       die Form:

           ptrace(Befehl, PID, 0, Signal);

       wobei  Befehl PTRACE_CONT, PTRACE_LISTEN, PTRACE_DETACH, PTRACE_SYSCALL, PTRACE_SINGLESTEP, PTRACE_SYSEMU
       oder PTRACE_SYSEMU_SINGLESTEP ist. Falls der verfolgte Prozess sich im  Signallieferstopp  befindet,  ist
       Signal  das  Signal, das eingespeist wird (falls es ungleich Null ist). Andernfalls kann Signal ignoriert
       werden. (Wenn ein verfolgter Prozess  von  einem  anderen  Ptrace-Stopp  als  dem  Signallieferstopp  neu
       gestartet wird, ist die empfohlene Vorgehensweise, 0 in Signal zu übergeben.)

   Anhängen und Loslösen
       Ein Thread kann an den Verfolger angehängt werden mit dem Aufruf

           ptrace(PTRACE_ATTACH, PID, 0, 0);

       oder

           ptrace(PTRACE_SEIZE, PID, 0, PTRACE_O_flags);

       PTRACE_ATTACH  sendet  außerdem SIGSTOP an diesen Thread. Falls der Verfolger möchte, dass dieser SIGSTOP
       keine Auswirkungen hat, muss er ihn unterdrücken. Beachten Sie, dass der  Verfolger,  falls  während  des
       Anhängens   gleichzeitig   weitere  Signale  an  diesen  Thread  gesandt  werden,  den  Eintritt  in  den
       Signallieferstopp mit anderen Signalen zuerst sieht! Die übliche Vorgehensweise ist,  diese  Signale  neu
       einzuspeisen,  bis  SIGSTOP  gesehen  wird  und  dann  die  Einspeisung  von SIGSTOP zu unterdrücken. Der
       Entwurfsfehler ist hierbei, dass sich ein Ptrace-Anhängen und ein gleichzeitig  gesandtes  SIGSTOP  einen
       Wettlauf liefern und das gleichzeitige SIGSTOP verloren gegangen sein kann.

       Da  Anhängen  SIGSTOP  sendet  und  der  Verfolger  es  üblicherweise  unterdrückt,  könnte dies zu einer
       herrenlosen EINTR-Rückgabe vom aktuell ausgeführten Systemaufruf in diesem verfolgten Prozess führen, wie
       er im Abschnitt »Signaleinspeisung und -unterdrückung« beschrieben wird.

       Seit Linux 3.4 kann PTRACE_SEIZE anstelle von PTRACE_ATTACH benutzt werden. PTRACE_SEIZE stoppt nicht den
       angehängten Prozess. Falls Sie ihn nach dem Anhängen (oder zu einem  anderen  Zeitpunkt)  stoppen  wollen
       ohne irgendwelche Signale zu senden, verwenden Sie den Befehl PTRACE_INTERRUPT.

       Die Anfrage

           ptrace(PTRACE_TRACEME, 0, 0, 0);

       verwandelt  den  aufrufenden Thread in einen verfolgten Prozess. Der Thread fährt mit der Ausführung fort
       (gerät nicht in den Ptrace-Stopp). Eine übliche Vorgehensweise besteht darin, PTRACE_TRACEME mit

           raise(SIGSTOP);

       zu folgen und dem Elternprozess (der nun der Verfolger ist)  zu  ermöglichen,  den  Signallieferstopp  zu
       beobachten.

       Falls die Optionen PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK oder PTRACE_O_TRACECLONE in Kraft sind, werden
       Kindprozesse mit vfork(2), beziehungsweise clone(2) mit dem Schalter CLONE_VFORK, fork(2)  oder  clone(2)
       mit  auf  SIGCHLD  gesetztem Beendigungssignal und anderen Arten von clone(2) automatisch an den gleichen
       Verfolger angehängt, der ihren Elternprozess verfolgte. SIGSTOP wird an die Kindprozesse gesandt, was sie
       veranlasst, in einen Signallieferstopp zu gelangen, nachdem sie den Systemaufruf beenden, der sie erzeugt
       hat.

       Loslösen des verfolgten Prozesses wird erreicht durch:

           ptrace(PTRACE_DETACH, PID, 0, Signal);

       PTRACE_DETACH ist eine  Neustartaktion;  daher  erfordert  sie,  dass  der  verfolgte  Prozess  in  einem
       Ptrace-Stopp ist. Falls der verfolgte Prozess in einem Signallieferstopp ist, kann ein Signal eingespeist
       werden. Andernfalls wird der Parameter Signal stillschweigend ignoriert.

       Falls der verfolgte Prozess läuft, wenn der Verfolger ihn loslösen möchte,  besteht  die  übliche  Lösung
       darin,  SIGSTOP  zu senden (mittels tgkill(2), um sicherzustellen, dass es an den korrekten Thread geht),
       darauf zu warten, dass der verfolgte Prozess in einen Signallieferstopp für SIGSTOP stoppt und  ihn  dann
       loszulösen  (SIGSTOP-Einspeisung  wird unterdrückt). Ein Entwurfsfehler besteht darin, dass sich dies mit
       gleichzeitigen SIGSTOPs Ressourcenwettläufe liefern kann. Eine weitere Komplikation besteht  darin,  dass
       der  verfolgte  Prozess  in  andere Ptrace-Stopps geraten kann und neu gestartet werden muss und nochmals
       gewartet werden muss, bis SIGSTOP gesehen wird. Noch eine weitere Komplikation besteht darin, dass  nicht
       sicher  ist,  ob  der verfolgte Prozess nicht bereits mit Ptrace gestoppt wurde, da keine Signallieferung
       stattfindet, obwohl es noch nicht einmal SIGSTOP ist.

       Falls der Verfolger stirbt, werden alle verfolgten Prozesse automatisch losgelöst und neu  gestartet,  es
       sei  denn,  sie  sind  im  Gruppenstopp.  Die  Handhabung  des Neustarts aus dem Gruppenstopp ist derzeit
       fehlerhaft, aber das »wie-geplant«-Verhalten ist, den verfolgten  Prozess  gestoppt  zu  lassen  und  auf
       SIGCONT  zu  warten.  Falls  der  verfolgte  Prozess  neu vom Signallieferstopp gestartet wurde, wird das
       ausstehende Signal einspeist.

   execve(2) unter Ptrace
       Wenn ein Thread in einem Prozess mit mehreren Threads execve(2) aufruft, zerstört der Kernel alle anderen
       Threads  im  Prozess  und  setzt  die  Thread-Kennung  des  ausführenden  Threads  auf die Gruppenkennung
       (Prozesskennung) zurück. (Oder anders ausgedrückt, wenn ein Prozess mit mehreren  Threads  ein  execve(2)
       bei  Vervollständigung  des  Aufrufs  ausführt,  scheint  es  durch das execve(2) im führenden Thread der
       Prozessgruppe aufzutreten, unabhängig davon, welcher Thread das execve(2) aufrief.)  Dieses  Zurücksetzen
       der Thread-Kennung sieht für Verfolger sehr verwirrend aus:

       •  Alle   anderen  Threads  stoppen  im  PTRACE_EVENT_EXIT-Stopp,  falls  die  Option  PTRACE_O_TRACEEXIT
          eingeschaltet wurde. Dann melden alle anderen Threads außer dem führenden Thread der Gruppe  den  Tod,
          als ob sie über _exit(2) mit dem Exit-Code 0 beendet worden wären.

       •  Der  ausführende,  verfolgte  Prozess  ändert  seine  Thread-Kennung, während er in dem execve(2) ist.
          (Denken Sie daran, unter Ptrace ist die von waitpid(2) zurückgegebene oder in Ptrace-Aufrufe gespeiste
          »PID«,  die  Thread-Kennung  des  verfolgten  Prozesses.)  Sprich,  die  Thread-Kennung des verfolgten
          Prozesses wird zurückgesetzt, so dass sie ihrer Prozesskennung entspricht, die dieselbe ist,  wie  die
          Thread-Kennung des führenden Threads der Thread-Gruppe.

       •  Dann  kommt  es  zu  einem  PTRACE_EVENT_EXEC-Stopp, falls die Option PTRACE_O_TRACEEXEC eingeschaltet
          wurde.

       •  Falls der führende Thread der Gruppe seinen PTRACE_EVENT_EXEC-Stopp mittlerweile gemeldet hat, scheint
          es für den Verfolger, als ob der tote führende Thread »aus dem Nichts wieder auftaucht«. (Hinweis: Der
          führende Thread der Gruppe meldet den  Tod  nicht  über  WIFEXITED(status)  bis  es  mindestens  einen
          lebenden anderen Thread gibt. Dies eliminiert die Möglichkeit, dass der Verfolger ihn sterben und dann
          erneut erscheinen sieht.) Falls der führende Thread der Gruppe immer noch lebt, könnte  dies  für  den
          Verfolger  so  aussehen,  als ob der führende Thread der Gruppe von einem anderen Systemaufruf als dem
          beigetretenen zurückkehrt oder  sogar  »von  einem  Systemaufruf  zurückkehrt,  obwohl  er  in  keinem
          Systemaufruf  war«.  Falls der führende Thread der Gruppe nicht verfolgt wurde (oder von einem anderen
          Verfolger verfolgt wurde), dann wird es während execve(2)  so  aussehen,  als  ob  er  ein  verfolgter
          Prozess des Verfolgers des ausführenden verfolgten Prozesses geworden wäre.

       All die Auswirkungen oberhalb sind Artefakte des Thread-Kennungswechsels im verfolgten Prozess.

       Die  Option  PTRACE_O_TRACEEXEC  ist  das empfohlene Werkzeug für den Umgang mit dieser Situation. Zuerst
       aktiviert es PTRACE_EVENT_EXEC-Stopp, der vor der Rückkehr von execve(2) auftritt. In diesem  Stopp  kann
       der  Verfolger  PTRACE_GETEVENTMSG verwenden, um die vorherige Thread-Kennung des verfolgten Prozesses zu
       erhalten.  (Diese  Funktion  wurde  in  Lunux  3.0  eingeführt.)  Als  zweites  deaktiviert  die   Option
       PTRACE_O_TRACEEXEC die alte SIGTRAP-Erzeugung auf execve(2).

       Wenn  der  Verfolger  die  PTRACE_EVENT_EXEC-Stoppbenachrichtigung  empfängt,  ist garantiert, dass außer
       diesem verfolgten Prozess und dem führenden  Thread  der  Gruppe  keine  anderen  Threads  des  Prozesses
       lebendig sind.

       Beim  Empfang  der  PTRACE_EVENT_EXEC-Stoppbenachrichtigung  sollte  der  Verfolger  all  seine  internen
       Datenstrukturen aufräumen, die Threads dieses Prozesses beschreiben und nur eine Datenstruktur  behalten,
       – eine, die den einzelnen, laufenden, verfolgten Prozess beschreibt mit

           Thread-Kennung == Thread-Gruppenkennung == Prozesskennung.

       Beispiel: Zwei Threads rufen zur gleichen Zeit execve(2) auf:

       *** wir bekommen einen Systemaufrufeintrittsstopp in Thread 1: **
       PID1 execve("/bin/foo", "foo" <nicht abgeschlossen …>
       *** wir liefern PTRACE_SYSCALL für Thread 1 **
       *** wir bekommen einen Systemaufrufeintrittsstopp in Thread 2: **
       PID2 execve("/bin/bar", "bar" <nicht abgeschlossen …>
       *** wir liefern PTRACE_SYSCALL für Thread 2 **
       *** wir bekommen PTRACE_EVENT_EXEC für PID0, wir liefern  PTRACE_SYSCALL **
       *** wir bekommen Systemaufrufbeendigungsstopp für PID0: **
       PID0 <… execve wieder aufgenommen> )             = 0

       Falls die Option PTRACE_O_TRACEEXEC für den ausführenden, verfolgten Prozess nicht in Kraft ist und falls
       der verfolgte Prozess PTRACE_ATTACHed statt PTRACE_SEIZEd war, sendet der Kernel ein zusätzliches SIGTRAP
       an den verfolgten Prozess, nachdem execve(2) zurückgekehrt ist. Dies ist ein gewöhnliches Signal (ähnlich
       einem, das durch kill -TRAP erzeugt werden kann), keine Spezialart eines Ptrace-Stopps. Unter Einsatz von
       PTRACE_GETSIGINFO für dieses Signal gibt si_code auf 0 gesetzt (SI_USER) zurück. Dieses Signal kann durch
       die Signalmaske blockiert sein und könnte daher (viel) später gesandt werden.

       Üblicherweise würde der Verfolger dem Anwender dieses zusätzliche SIGTRAP-Signal nach Execve nicht zeigen
       wollen  und seinen Versand an den verfolgten Prozess unterdrücken (falls SIGTRAP auf SIGTRAP gesetzt ist,
       killt es das Signal). Es ist jedoch nicht einfach zu bestimmen, welches SIGTRAP zu unterdrücken ist.  Die
       empfohlene  Herangehensweise  ist, die Option PTRACE_O_TRACEEXEC zu setzen oder PTRACE_SEIZE zu verwenden
       und damit dieses zusätzliche SIGTRAP zu unterdrücken.

   Echter Elternprozess
       Die Ptrace-Programmierschnittstelle (miss)braucht die Standard-UNIX-Eltern-/Kindprozess-Signalgebung über
       waitpid(2).  Diese  wird  benutzt,  um den echten Elternprozess zum Stopp des Empfangs mehrerer Arten von
       waitpid(2)-Benachrichtigungen zu veranlassen, wenn der Kindprozess durch einen anderen  Prozess  verfolgt
       wird.

       Viele  dieser  Fehler  wurden  behoben,  aber ab Linux 2.6.38 existieren etliche immer noch; siehe FEHLER
       oberhalb.

       Ab Linux 2.6.38 wird davon ausgegangen, dass folgendes korrekt funktioniert:

       •  Beenden/Sterben durch Signal wird zuerst an den Verfolger  gemeldet,  dann,  wenn  der  Verfolger  das
          waitpid(2)-Ergebnis verbraucht, an den echten Elternprozess (an den echten Elternprozess nur, wenn der
          ganze Prozess aus mehreren Threads  existiert).  Falls  der  Verfolger  und  der  echte  Elternprozess
          derselbe Prozess sind, wird der Bericht nur einmal gesandt.

RÜCKGABEWERT

       Bei  Erfolg  geben die PTRACE_PEEK*-Anfragen die angeforderten Daten zurück (aber siehe die ANMERKUNGEN),
       die Anfrage PTRACE_SECCOMP_GET_FILTER liefert die Anzahl der Anweisungen in dem BPF-Programm zurück,  die
       Anfrage  PTRACE_GET_SYSCALL_INFO  liefert  die Anzahl der Byte zurück, die zum Schreiben durch den Kernel
       verfügbar sind und andere Anfragen geben Null zurück.

       Bei einem Fehler geben alle Anfragen -1 zurück und errno wird gesetzt, um den Fehler anzuzeigen.  Da  der
       Wert,  der  von  einer  erfolgreichen  PTRACE_PEEK*-Anfrage zurückgegeben wurde, -1 sein könnte, muss der
       Aufrufende vor dem Aufruf errno leeren und es dann hinterher untersuchen, um festzustellen, ob ein Fehler
       aufgetreten ist oder nicht.

FEHLER

       EBUSY  (nur i386) Es ist beim Reservieren oder der Freigabe eines Debug-Registers ein Fehler aufgetreten.

       EFAULT Es  gab  einen  Versuch in einem ungültigen Bereich im Speicher des Verfolgers oder des verfolgten
              Prozesses zu lesen oder zu schreiben, wahrscheinlich, weil der Bereich nicht abgebildet  war  oder
              kein  Zugriff  möglich  war.  Unglücklicherweise  geben  unter  Linux  mehrere  Variationen dieser
              Ausnahmebehandlung mehr oder weniger willkürlich EIO oder EFAULT zurück.

       EINVAL Es wurde versucht, eine ungültige Option zu setzen.

       EIO    Anfrage ist ungültig, es wurde versucht, in einem ungültigen Bereich im  Speicher  des  Verfolgers
              oder  des  verfolgten Prozesses zu lesen oder zu schreiben, es gab eine Verletzung der Ausrichtung
              an der »word«-Größe oder es  wurde  während  des  Neustarts  der  Abfrage  ein  ungültiges  Signal
              angegeben.

       EPERM  Der  angegebene  Prozess  kann nicht verfolgt werden. Dies könnte daher rühren, dass der Verfolger
              über  unzureichende  Privilegien  verfügt   (die   Capability   CAP_SYS_PTRACE   wird   benötigt);
              unprivilegierte  Prozesse  können  keine Prozesse verfolgen, denen sie keine Signale senden können
              oder die SUID-/SGID-Programme ausführen,  was  naheliegend  ist.  Alternativ  könnte  der  Prozess
              bereits verfolgt werden oder (Linux vor 2.6.26) init(1) (PID 1) sein.

       ESRCH  Der angegebene Prozess existiert nicht, wird derzeit nicht vom Aufrufenden verfolgt oder ist nicht
              gestoppt (bei Anfragen, die einen gestoppten verfolgten Prozess erfordern).

STANDARDS

       SVr4, 4.3BSD.

ANMERKUNGEN

       Obwohl Argumente für ptrace() gemäß dem angegebenen Prototypen  interpretiert  werden,  deklariert  Glibc
       derzeit ptrace() als eine variable Funktion mit nur dem festen Anfrage-Argument. Es wird empfohlen, immer
       vier Argumente anzugeben, sogar dann, wenn die  angeforderte  Aktion  sie  nicht  verwendet.  Setzen  Sie
       unbenutzte/ignorierte Argumente auf 0L oder (void *) 0.

       In Linux-Versionen vor 2.6.26 kann init(1) den Prozess mit der Prozessnummer 1 nicht verfolgen.

       Der  Elternprozess  des verfolgten Prozesses wird weiterhin der Verfolger sein, selbst wenn der Verfolger
       execve(2) aufruft.

       Das  Layout  des  Speicherinhalts   und   des   BENUTZERbereichs   sind   ziemlich   betriebsystem-   und
       architekturspezifisch.  Der  mitgelieferte  Versatz  und  die zurückgegebenen Daten passen möglicherweise
       nicht ganz zu der Definition von struct user.

       Die Größe eines »word« wird durch die Betriebsystemvariante festgelegt (z.B. ist es für ein  32-Bit-Linux
       32 Bit).

       Diese  Seite  dokumentiert  die  Möglichkeit,  wie  der  ptrace()-Aufruf  derzeit in Linux arbeitet. Sein
       Verhalten unterscheidet sich auf anderen unixoiden Betriebssystemen deutlich.  Auf  jeden  Fall  ist  die
       Benutzung von ptrace() in hohem Grad abhängig vom Betriebssystem und der Architektur.

   Ptrace-Zugriffsmodusüberprüfung
       Verschiedene  Teile  des  Kernel-Benutzerraum-APIs  (nicht  nur  ptrace()-Aktionen)  benötigen sogenannte
       »Ptrace-Zugriffsmodusüberprüfungen«, deren Ergebnis bestimmt, ob eine Aktion erlaubt  (oder,  in  wenigen
       Fällen,  einer  »Lese«-Aktion  bereinigte Daten zurückliefern) wird. Diese Überprüfungen werden in Fällen
       durchgeführt, in denen ein Prozess vertrauliche Informationen über einen anderen Prozess einsehen  könnte
       oder  in  einigen  Fällen den Zustand eines anderen Prozesse verändern könnte. Die Überprüfungen basieren
       auf Faktoren wie den Berechtigungsnachweisen und den Capabilitys der zwei Prozesse, ob der Speicherinhalt
       des »Zielprozesses« ausgegeben werden kann und dem Ergebnis der Überprüfungen, die durch jedes aktivierte
       Linux-Sicherheitsmodul (LSM) – zum Beispiel SELinux, Yama oder Smack – und durch das  Commoncap-LSM  (das
       immer ausgeführt wird), ausgeführt wird.

       Vor  Linux  2.6.27  waren  alle  Zugriffsprüfungen  von einem einzigen Typ. Seit Linux 2.6.27 werden zwei
       Zugriffsmodi unterschieden:

       PTRACE_MODE_READ
              Für »Lese«-Aktionen oder andere Aktionen, die weniger  gefährlich  sind,  wie  get_robust_list(2);
              kcmp(2);  Lesen  aus /proc/PID/auxv, /proc/PID/environ oder /proc/PID/stat; oder readlink(2) einer
              /proc/PID/ns/*-Datei.

       PTRACE_MODE_ATTACH
              Für »Schreibe«-Aktionen oder  andere  Aktionen,  die  gefährlicher  sind,  wie  Ptrace-Anhängungen
              (PTRACE_ATTACH)    an    einen    anderen   Prozess   oder   Aufrufe   von   process_vm_writev(2).
              (PTRACE_MODE_ATTACH war tatsächlich die Vorgabe vor Linux 2.6.27.)

       Seit Linux 4.5 sind die obigen Zugriffsmodusprüfungen mittels ODER mit einem der folgenden  Modifikatoren
       verknüpft:

       PTRACE_MODE_FSCREDS
              Die   Dateisystem-UID  und  -GID  (siehe  credentials(7))  oder  die  effektiven  Capabilitys  für
              LSM-Prüfungen des Aufrufenden verwenden.

       PTRACE_MODE_REALCREDS
              Die reale UID und GID oder die erlaubten Capabilitys für LSM-Prüfungen des Aufrufenden  verwenden.
              Dies war vor Linux 4.5 die Vorgabe.

       Da die Kombination eines der Berechtigungsnachweise-Modifikatoren mit einem der vorgenannten Zugriffsmodi
       typisch ist, sind ein paar Makros in den Kernelquellen für die Kombinationen definiert.

       PTRACE_MODE_READ_FSCREDS
              Definiert als PTRACE_MODE_READ | PTRACE_MODE_FSCREDS.

       PTRACE_MODE_READ_REALCREDS
              Definiert als PTRACE_MODE_READ | PTRACE_MODE_REALCREDS.

       PTRACE_MODE_ATTACH_FSCREDS
              Definiert als PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS.

       PTRACE_MODE_ATTACH_REALCREDS
              Definiert als PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS.

       Ein weiterer Modifikator kann mit den Zugriffsmodus mittels ODER verknüpft werden:

       PTRACE_MODE_NOAUDIT (seit Linux 3.3)
              Diese    Zugriffsmodusprüfung    nicht     auditieren.     Dieser     Modifikator     wird     für
              Ptrace-Zugriffsmodusprüfungen  eingesetzt  (wie z.B. Prüfungen beim Lesen von /proc/PID/stat), die
              lediglich die Ausgabe filtern oder bereinigen, statt dem Aufrufenden einen Fehler zurückzuliefern.
              In  diesen  Fällen  ist  der  Zugriff auf die Datei keine Sicherheitsverletzung und es gibt keinen
              Grund, einen Sicherheitsauditdatensatz zu erstellen. Dieser Modifikator unterdrückt die Erstellung
              eines solchen Auditdatensatzes für diese Zugriffsprüfung.

       Beachten  Sie, dass alle in diesem Unterabschnitt beschriebenen Konstanten PTRACE_MODE_* kernelintern und
       nicht im Anwendungsraum sichtbar sind. Die Konstantennamen werden  hier  benannt,  um  den  verschiedenen
       Arten  von Ptrace-Zugriffsmodusprüfungen, die für verschiedene Systemaufrufe und Zugriff auf verschiedene
       Pseudodateien (z.B. unter /proc) durchgeführt werden, einen Namen zu geben. Diese Namen werden in anderen
       Handbuchseiten  benutzt,  um  eine einfache Abkürzung für die Benennung der verschiedenen Kernelprüfungen
       bereitzustellen.

       Der für Ptrace-Zugriffsmodusprüfungen  eingesetzte  Algorithmus  bestimmt,  ob  dem  aufrufenden  Prozess
       erlaubt  wird,  die  entsprechende  Aktion  auf  dem Zielprozess durchzuführen. (Im Falle des Öffnens von
       /proc/[PID]-Dateien ist der »aufrufende Prozess« derjenige, der die Datei öffnet, und der Prozess mit der
       entsprechenden PID der »Zielprozess«). Der Algorithmus geht wie folgt:

       (1)  Falls der aufrufende Thread und der Ziel-Thread in der gleichen Thread-Gruppe sind, wird der Zugriff
            immer erlaubt.

       (2)  Falls der Zugriffsmodus PTRACE_MODE_FSCREDS festlegt, dann wird für die Prüfung im nächsten  Schritt
            die  Dateisystem-UID  und  -GID des Aufrufenden verwandt. (Wie in credentials(7) vermerkt, haben die
            Dateisystem-UID und -GID fast immer die gleichen Werte wie die entsprechenden effektiven Kennungen.)

            Andernfalls legt der Zugriffsmodus PTRACE_MODE_REALCREDS fest, so dass die reale UID und GID für die
            Prüfungen  im  nächsten  Schritt  verwandt  werden.  (Die  meisten  APIs,  die die UIDs und GIDs des
            Aufrufenden prüfen, verwenden effektive Kennungen. Aus historischen Gründen  verwendet  die  Prüfung
            PTRACE_MODE_REALCREDS stattdessen die realen Kennungen.)

       (3)  Zugriff verweigern, falls keines der Folgenden wahr ist:

            •  Die   reale,   effektive   und   saved-set-Benutzerkennungen   des  Zieles  passen  auf  die  der
               Benutzerkennung des Aufrufenden und die reale, effektive und saved-set-Gruppenkennung des  Zieles
               passen auf die der Gruppenkennung des Aufrufenden.

            •  Der Aufrufende verfügt über die Capability CAP_SYS_PTRACE in dem Benutzernamensraum des Ziels.

       (4)  Verweigert  den  Zugriff,  falls  das  Attribut »dumpable« einen anderen Wert als 1 (SUID_DUMP_USER,
            siehe die Diskussion von PR_SET_DUMPABLE  in  prctl(2))  hat  und  der  Aufrufende  nicht  über  die
            Capability CAP_SYS_PTRACE in dem Benutzernamensraum des Zielprozesses verfügt.

       (5)  Die  Schnittstelle security_ptrace_access_check() wird aufgerufen, um zu erkennen, ob Ptrace-Zugriff
            erlaubt ist. Das Ergebnis hängt von dem/den LSM(en) ab. Die Implementierung dieser Schnittstelle  im
            LSM Commoncap führt die folgenden Schritte durch:

            (5.1)  Falls der Zugriffsmodus PTRACE_MODE_FSCREDS enthält, dann wird die effektive Capability-Menge
                   des Aufrufenden in der nachfolgenden Prüfung verwandt, andernfalls  (der  Zugriffsmodus  legt
                   PTRACE_MODE_REALCREDS fest) wird die erlaubte Capability-Menge des Aufrufenden verwandt.

            (5.2)  Zugriff verweigern, falls keines der Folgenden wahr ist:

                   •  Der aufrufende und der Zielprozess sind im gleichen Benutzernamensraum und die Capabilitys
                      des Aufrufenden sind eine Obermenge der erlaubten Capabilitys des Zielprozesses.

                   •  Der Aufrufende verfügt über die Capability CAP_SYS_PTRACE in  dem  Benutzernamensraum  des
                      Zielprozesses.

                   Beachten  Sie,  dass das LSM Commoncap nicht zwischen PTRACE_MODE_READ und PTRACE_MODE_ATTACH
                   unterscheidet.

       (6)  Falls der Zugriff in den vorhergehenden Schritten nicht verweigert wurde, dann wird er erlaubt.

   /proc/sys/kernel/yama/ptrace_scope
       Auf Systemen, auf  denen  das  Yama  Linux  Security  Module  (LSM)  installiert  (d.h.  der  Kernel  mit
       CONFIG_SECURITY_YAMA   konfiguriert   worden)  ist,  kann  die  Datei  /proc/sys/kernel/yama/ptrace_scope
       (verfügbar seit Linux 3.4) zum Einschränken der Nachverfolgung von Prozessen mit ptrace() verwandt werden
       (und damit auch die Möglichkeit, Werkzeuge wie strace(1) und gdb(1) zu verwenden). Das Ziel einer solchen
       Einschränkung besteht darin, Angriffseskalationen zu vermeiden, bei denen  ein  kompromittierter  Prozess
       sich  mittels Ptrace-attach an andere sensitive Prozesse (z.B. einem GPG-Agenten oder einer SSH-Sitzung),
       die dem Benutzer gehören, anhängen könnte, um zusätzliche  Berechtigungsnachweise  zu  erlangen,  die  im
       Speicher existieren, und damit den Umfang des Angriffs zu erhöhen.

       Genauer gesagt begrenzt die Yama LSM zwei Arten von Aktionen:

       •  Jede  Aktion,  die  eine  Ptrace-Zugriffsmodusprüfung  PTRACE_MODE_ATTACH  durchführt – beispielsweise
          ptrace() PTRACE_ATTACH. (Siehe die obige Diskussion »Ptrace-Zugriffsmodusüberprüfung«).

       •  ptrace() PTRACE_TRACEME.

       Ein    Prozess,    der    über    die    Capability    CAP_SYS_PTRACE    verfügt,    kann    die    Datei
       /proc/sys/kernel/yama/ptrace_scope mit einem der folgenden Werte aktualisieren:

       0 (»klassische Ptrace-Berechtigungen«)
              Keine  zusätzlichen  Beschränkungen bei Aktionen, die PTRACE_MODE_ATTACH-Überprüfungen durchführen
              (die über die von Commoncap und anderen LSMs hinausgehen).

              PTRACE_TRACEME wird unverändert verwandt.

       1 (»eingeschränkter Ptrace«) [Vorgabewert]
              Wenn eine Aktion durchgeführt wird, die eine  PTRACE_MODE_ATTACH-Überprüfung  benötigt,  muss  der
              aufrufende  Prozess  entweder  über  die  Capability  CAP_SYS_PTRACE in dem Benutzernamensraum des
              Zielprozesses  verfügen  oder  er  muss  eine  vorbestimmte  Beziehung  zum   Zielprozess   haben.
              Standardmäßig  ist  die vorbestimmte Beziehung, dass der Zielprozess ein Nachkomme des Aufrufenden
              sein muss.

              Ein Zielprozess kann die prctl(2)-Aktion PR_SET_PTRACER einsetzen,  um  eine  zusätzliche  PID  zu
              erklären,  der  es  erlaubt ist, PTRACE_MODE_ATTACH-Aktionen auf dem Ziel durchzuführen. Siehe die
              Kernelquelldatei Documentation/admin-guide/LSM/Yama.rst (oder Documentation/security/Yama.txt  vor
              Linux 4.13) für weitere Details.

              PTRACE_TRACEME wird unverändert verwandt.

       2 (»nur Admin-Anhängung«)
              Nur  Prozesse  mit  der  Capability  CAP_SYS_PTRACE im Benutzernamensraum des Zielprozesses dürfen
              PTRACE_MODE_ATTACH-Aktionen durchführen oder Kinder, die PTRACE_TRACEME einsetzen, verfolgen.

       3 (»keine Anhängung«)
              Kein  Prozess  darf  PTRACE_MODE_ATTACH-Aktionen  durchführen  oder  Kindprozesse  verfolgen,  die
              PTRACE_TRACEME einsetzen.

              Sobald dieser Wert in die Datei geschrieben wurde, kann er nicht mehr geändert werden.

       Beachten  Sie  im  Hinblick  auf  die  Werte 1 und 2, dass die Erstellung eines neuen Benutzernamensraums
       effektiv den durch Yama bereitgestellten Schutz entfernt. Dies rührt  daher,  dass  der  Prozess  in  dem
       Elternbenutzerraum,  dessen effektive UID auf die UID des Erstellers des Kindnamensraums passt, über alle
       Capabilitys (einschließlich CAP_SYS_PTRACE) verfügt, wenn er Aktionen innerhalb des Kindnamensraums  (und
       weiter   entfernter   Nachkommen  dieses  Namensraums)  durchführt.  Wenn  ein  Prozess  versucht,  einen
       Benutzernamensraum zu verwenden, um sich in eine Sandbox zu bringen, wird er konsequenterweise den  durch
       das Yama LSM bereitgestellten Schutz schwächen.

   Unterschiede C-Bibliothek/Kernel
       Auf  der  Systemaufrufebene  haben die Anfragen PTRACE_PEEKTEXT, PTRACE_PEEKDATA und PTRACE_PEEKUSER eine
       unterschiedliche Programmierschnittstelle: Sie speichern das Ergebnis an der durch  den  Parameter  Daten
       angegebenen  Adresse  und der Rückgabewert ist ein Fehlercode. Die Glibc-Wrapper-Funktion stellt die oben
       in BESCHREIBUNG angegebene Programmierschnittstelle bereit. Ihr Ergebnis wird über den  Rückgabewert  der
       Funktion zurückgegeben.

FEHLER

       Auf Rechnern mit 2.6 Linux-Headern ist PTRACE_SETOPTIONS mit einem anderen Wert deklariert, als auf einem
       für 2.4. Dies führt dazu,  dass  Anwendungen,  die  mit  2.6-Linux-Headern  kompiliert  wurden,  bei  der
       Ausführung  auf  2.4er  Kerneln  scheitern.  Dies  kann  durch  Neudefinieren  von  PTRACE_SETOPTIONS  zu
       PTRACE_OLDSETOPTIONS umgangen werden, wenn dies definiert ist.

       Gruppenstoppbenachrichtigungen werden an der Verfolger gesandt, aber nicht an den  echten  Elternprozess.
       Zuletzt auf 2.6.38.6 bestätigt.

       Falls  ein führender Thread einer Gruppe verfolgt und durch den Aufruf von _exit(2) beendet wird, wird es
       für  ihn  zu  einem  PTRACE_EVENT_EXIT-Stopp  kommen   (falls   angefordert),   aber   die   nachfolgende
       WIFEXITED-Benachrichtigung  wird  nicht gesandt, bis alle anderen Threads beendet sind. Wie oben erklärt,
       wird der Tod des führenden Prozesses der Gruppe gemeldet,  falls  einer  der  anderen  Threads  execve(2)
       aufruft. Falls der ausgeführte Thread nicht durch den Verfolger verfolgt wird, wird der Verfolger niemals
       erfahren, dass execve(2) auftrat. Eine mögliche Notlösung ist ein PTRACE_DETACH für den führenden  Thread
       der Gruppe, anstatt ihn in diesem Fall neu zu starten. Zuletzt auf 2.6.38.6 bestätigt.

       Ein  SIGKILL-Signal  kann  immer  noch  einen  PTRACE_EVENT_EXIT-Stopp  vor  dem  tatsächlichen Signaltod
       verursachen. Dies könnte in Zukunft geändert werden; SIGKILL ist dazu gedacht, Aufgaben immer  sofort  zu
       killen, sogar unter Ptrace. Zuletzt auf Linux 3.13 bestätigt.

       Einige  Systemaufrufe  kehren  mit  EINTR zurück, falls ein Signal an den verfolgten Prozess gesandt, die
       Auslieferung aber durch den Verfolger unterdrückt wurde. (Dies ist eine ganz typische  Aktion:  Sie  wird
       normalerweise  von  Fehlersuchprogrammen  bei  jedem  Anhängen  durchgeführt,  um kein fingiertes SIGSTOP
       einzuleiten.)  Ab  Linux  3.2.9  werden  die  folgenden  Systemaufrufe  beeinflusst  (diese   Liste   ist
       wahrscheinlich  nicht  vollständig):  epoll_wait(2) und read(2) von einem inotify(7)-Dateideskriptor. Das
       übliche Anzeichen für diesen Fehler ist, falls Sie einen ruhenden Prozess mit dem Befehl

           strace -p <Prozesskennung>

       anhängen, dass Sie statt der erwarteten einzeiligen Ausgabe, wie

           restart_syscall(<… resuming interrupted call …>_

       oder

           select(6, [5], NULL, [5], NULL_

       ('_' kennzeichnet die Cursor-Position) mehr als eine Zeile beobachten können, zum Beispiel:

               clock_gettime(CLOCK_MONOTONIC, {15370, 690928118}) = 0
               epoll_wait(4,_

       Was hier nicht sichtbar ist, ist, dass der Prozess in epoll_wait(2) blockiert wurde, bevor  strace(1)  an
       ihn angehängt hat. Das Anhängen verursachte ein epoll_wait(2), um zum Anwendungsraum mit dem Fehler EINTR
       zurückzukehren. In diesem besonderen Fall reagiert das  Programm  auf  EINTR,  indem  die  aktuelle  Zeit
       geprüft  und  dann  epoll_wait(2)  erneut  ausgeführt  wird. (Programme, die keine derartigen »verirrten«
       EINTR-Fehler erwarten, können sich bei einem strace(1)-Anhängen in unbeabsichtigter Weise verhalten.)

       Entgegen den normalen Regeln kann der Glibc-Wrapper für ptrace() errno auf Null setzen.

SIEHE AUCH

       gdb(1),  ltrace(1),  strace(1),  clone(2),   execve(2),   fork(2),   gettid(2),   prctl(2),   seccomp(2),
       sigaction(2), tgkill(2), vfork(2), waitpid(2), exec(3), capabilities(7), signal(7)

ÜBERSETZUNG

       Die  deutsche  Übersetzung  dieser  Handbuchseite  wurde  von  Patrick Rother <krd@gulu.net>, Chris Leick
       <c.leick@vollbio.de>,   Mario   Blättermann   <mario.blaettermann@gmail.com>   und    Helge    Kreutzmann
       <debian@helgefjell.de> erstellt.

       Diese  Übersetzung  ist  Freie  Dokumentation;  lesen  Sie  die  GNU  General  Public  License  Version 3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE
       HAFTUNG übernommen.

       Wenn  Sie  Fehler  in  der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die
       Mailingliste der Übersetzer ⟨debian-l10n-german@lists.debian.org⟩.