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

BEZEICHNUNG

       ptrace - Prozessverfolgung

BIBLIOTHEK

       Standard-C-Bibliothek (libc, -lc)

ÜBERSICHT

       #include <sys/ptrace.h>

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

BESCHREIBUNG

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

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

           ptrace(PTRACE_foo, PID, …)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                     Die PID des neuen Prozesses kann mit PTRACE_GETEVENTMSG abgefragt werden.

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

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

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

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

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

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

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

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

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

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

                     Die PID des neuen Prozesses kann mit PTRACE_GETEVENTMSG abgefragt werden.

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

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

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

                     Die PID des neuen Prozesses kann mit PTRACE_GETEVENTMSG abgefragt werden.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

              Die Struktur ptrace_syscall_info enthält die folgenden Felder:

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

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

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

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

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

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

              PTRACE_SYSCALL_INFO_NONE
                     Keine Komponente der Union enthält relevante Informationen.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

           ptrace(PTRACE_restart, PID, 0, Signal)

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

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

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

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

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

           ptrace(PTRACE_restart, PID, 0, Stoppsignal)

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

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

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

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

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

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

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

           ptrace(PTRACE_GETSIGINFO, PID, 0, &siginfo)

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

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

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

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

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

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

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

           ((PTRACE_EVENT_foo<<8) | SIGTRAP).

       Es gibt die folgenden Ereignisse:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

       Der Aufruf

           ptrace(PTRACE_SETOPTIONS, PID, 0, PTRACE_O_flags);

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

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

           ptrace(Befehl, PID, 0, Signal);

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

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

           ptrace(PTRACE_ATTACH, PID, 0, 0);

       oder

           ptrace(PTRACE_SEIZE, PID, 0, PTRACE_O_flags);

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

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

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

       Die Anfrage

           ptrace(PTRACE_TRACEME, 0, 0, 0);

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

           raise(SIGSTOP);

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

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

       Loslösen des verfolgten Prozesses wird erreicht durch:

           ptrace(PTRACE_DETACH, PID, 0, Signal);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

RÜCKGABEWERT

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

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

FEHLER

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

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

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

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

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

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

STANDARDS

       SVr4, 4.3BSD.

ANMERKUNGEN

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

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

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

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

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

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

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

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

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

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

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

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

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

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

       PTRACE_MODE_READ_FSCREDS
              Definiert als PTRACE_MODE_READ | PTRACE_MODE_FSCREDS.

       PTRACE_MODE_READ_REALCREDS
              Definiert als PTRACE_MODE_READ | PTRACE_MODE_REALCREDS.

       PTRACE_MODE_ATTACH_FSCREDS
              Definiert als PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS.

       PTRACE_MODE_ATTACH_REALCREDS
              Definiert als PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

       Genauer gesagt begrenzt die Yama LSM zwei Arten von Aktionen:

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

       •  ptrace() PTRACE_TRACEME.

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

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

              PTRACE_TRACEME wird unverändert verwandt.

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

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

              PTRACE_TRACEME wird unverändert verwandt.

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

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

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

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

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

FEHLER

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

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

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

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

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

           strace -p <Prozesskennung>

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

           restart_syscall(<… resuming interrupted call …>_

       oder

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

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

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

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

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

SIEHE AUCH

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

ÜBERSETZUNG

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

       Diese  Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer
       bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.

       Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte  eine  E-Mail  an  die
       Mailingliste der Übersetzer.

Linux man-pages 6.03                             5. Februar 2023                                       ptrace(2)