Provided by: manpages-de-dev_2.16-1_all bug

BEZEICHNUNG

       ptrace - Prozessverfolgung

Ü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_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,
              festlegt. 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)
              Retrieve information about the system call that caused the stop. The information is
              placed into the buffer pointed by the data argument, which should be a pointer to a
              buffer  of  type struct ptrace_syscall_info. The addr argument contains the size of
              the   buffer   pointed   to   by   the   data   argument    (i.e.,    sizeof(struct
              ptrace_syscall_info)).  The  return value contains the number of bytes available to
              be written by the kernel. If the size of the data  to  be  written  by  the  kernel
              exceeds the size specified by the addr argument, the output data is truncated.

              Die Struktur ptrace_syscall_info enthält die folgenden Felder:

                struct ptrace_syscall_info {
                    __u8 op;         /* Type of system call stop */
                    __u32 arch;      /* AUDIT_ARCH_* value; see seccomp(2) */
                    __u64 instruction_pointer; /* CPU instruction pointer */
                    __u64 stack_pointer;       /* CPU stack pointer */
                    union {
                        struct {     /* op == PTRACE_SYSCALL_INFO_ENTRY */
                            __u64 nr;          /* System call number */
                            __u64 args[6];     /* System call arguments */
                        } entry;
                        struct {     /* op == PTRACE_SYSCALL_INFO_EXIT */
                            __s64 rval;        /* System call return value */
                            __u8 is_error;     /* System call error flag;
                                                  Boolean: does rval contain
                                                  an error value (-ERRCODE) or
                                                  a nonerror return value? */
                        } exit;
                        struct {     /* op == PTRACE_SYSCALL_INFO_SECCOMP */
                            __u64 nr;          /* System call number */
                            __u64 args[6];     /* System call arguments */
                            __u32 ret_data;    /* SECCOMP_RET_DATA portion
                                                  of SECCOMP_RET_TRACE
                                                  return value */
                        } seccomp;
                    };
                };

              The  op,  arch,  instruction_pointer,  and stack_pointer fields are defined for all
              kinds of ptrace system call stops. The rest of the structure is a union; one should
              read  only  those  fields  that  are  meaningful  for  the kind of system call stop
              specified by the op field.

              The op field  has  one  of  the  following  values  (defined  in  <linux/ptrace.h>)
              indicating what type of stop occurred and which part of the union is filled:

              PTRACE_SYSCALL_INFO_ENTRY
                     The  entry  component of the union contains information relating to a system
                     call entry stop.

              PTRACE_SYSCALL_INFO_EXIT
                     The exit component of the union contains information relating  to  a  system
                     call exit stop.

              PTRACE_SYSCALL_INFO_SECCOMP
                     The  exit  component  of  the  union  contains  information  relating  to  a
                     PTRACE_EVENT_SECCOMP stop.

              PTRACE_SYSCALL_INFO_NONE
                     No component of the union contains relevant information.

   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)  true«  zurück  und  WSTOPSIG(status) gibt SIGTRAP zurück. Es wird ein
       zusätzliches Bit in das höhere Bit des Status (Datentyp Word) gesetzt: Der Wert  status>>8
       wird wie folgt sein:

           (SIGTRAP | PTRACE_EVENT_foo << 8).

       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 und andere Anfragen geben Null zurück.

       Bei einem Fehler geben alle Anfragen -1 zurück und errno wird entsprechend gesetzt. 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 (auf
              Kerneln 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).

KONFORM ZU

       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-Kerneln 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:

          a) 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.

          b) 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  Kernel-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-Kernel-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)

KOLOPHON

       Diese Seite  ist  Teil  der  Veröffentlichung  5.03  des  Projekts  Linux-man-pages.  Eine
       Beschreibung  des  Projekts,  Informationen,  wie  Fehler gemeldet werden können sowie die
       aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.

Ü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  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 <debian-l10n-german@lists.debian.org>.