dwww Home | Manual pages | Find package

ptrace(2)                     System Calls Manual                    ptrace(2)

NOM
       ptrace - Suivre un processus

BIBLIOTHÈQUE
       Bibliothèque C standard (libc, -lc)

SYNOPSIS
       #include <sys/ptrace.h>

       long ptrace(enum __ptrace_request request, pid_t pid,
                   void *addr, void *data);

DESCRIPTION
       L'appel  système ptrace() fournit à un processus (l'« observateur ») un
       moyen d'observer et  de  contrôler  l'exécution  d'un  autre  processus
       (l'« observé »), et d'examiner et éditer la mémoire et les registres de
       l'observé. L'utilisation principale de cette fonction est l'implémenta-
       tion de points d'arrêt pour le débogage, et pour suivre les appels sys-
       tème.

       Un observé doit d'abord être attaché à l'observateur. L'attachement  et
       les  commandes  suivantes  sont  par  thread : dans un processus multi-
       threadé, chaque thread peut être attaché individuellement à un observa-
       teur (éventuellement différent), ou être laissé détaché et donc non dé-
       bogué. Par conséquent, l'« observé » signifie toujours « (un) thread »,
       jamais  « un  processus  (éventuellement multithreadé) ». Les commandes
       ptrace sont toujours envoyées à un observé spécifique en  utilisant  un
       appel de la forme

           ptrace(PTRACE_truc, pid, ...)

       où pid est l'identifiant de thread du thread Linux correspondant.

       (Remarquez  que dans cette page, un « processus multithreadé » signifie
       un groupe de threads constitué de threads créés en utilisant l'attribut
       CLONE_THREAD de clone(2).)

       Un  processus  peut  démarrer  un suivi en appelant fork(2) et faire en
       sorte que l'enfant créé fasse un PTRACE_TRACEME, suivi (en général) par
       un  execve(2). Autrement, un processus peut commencer à suivre un autre
       processus en utilisant PTRACE_ATTACH ou PTRACE_SEIZE.

       L'observé s'arrêtera à chaque fois qu'un  signal  lui  sera  distribué,
       même si le signal est ignoré (à l'exception de SIGKILL qui a les effets
       habituels). L'observateur sera prévenu à son prochain  appel  de  wait-
       pid(2)  (ou un des appels système liés à « wait ») ; cet appel renverra
       une valeur status contenant les renseignements indiquant la  raison  de
       l'arrêt  de l'observé. Lorsque l'observé est arrêté, l'observateur peut
       utiliser plusieurs requêtes ptrace pour  inspecter  et  modifier  l'ob-
       servé.  L'observateur  peut  également laisser continuer l'exécution de
       l'observé, en ignorant éventuellement le signal ayant  déclenché  l'ar-
       rêt, ou même en envoyant un autre signal.

       Si  l'option  PTRACE_O_TRACEEXEC  n'est  pas effective, tous les appels
       réussis d'execve(2) par le processus suivi déclencheront  l'envoi  d'un
       signal  SIGTRAP, ce qui permet au parent de reprendre le contrôle avant
       que le nouveau programme commence son exécution.

       Quand l'observateur a fini le suivi, il peut forcer l'observé à  conti-
       nuer normalement, en mode non suivi, avec PTRACE_DETACH.

       La  valeur  de l'argument request indique précisément l'action à entre-
       prendre.

       PTRACE_TRACEME
              Le processus en cours va être suivi par son parent. Un processus
              ne  devrait  sans  doute pas envoyer cette requête si son parent
              n'est pas prêt à le suivre. Dans cette  requête  pid,  addr,  et
              data sont ignorés.

              La  requête  PTRACE_TRACEME ne sert qu'à l'observé. Les requêtes
              restantes ne servent qu'à l'observateur. Par la suite, pid  pré-
              cise  l'identifiant de thread de l'observé sur lequel agir. Pour
              d'autres requêtes que PTRACE_ATTACH, PTRACE_SEIZE, PTRACE_INTER-
              RUPT et PTRACE_KILL, l'observé doit être arrêté.

       PTRACE_PEEKTEXT, PTRACE_PEEKDATA
              Lire  un mot à l'adresse addr dans l'espace mémoire de l'observé
              et le renvoyer en résultat de l'appel ptrace(). Linux ne  sépare
              pas les espaces d'adressage de code et de données, donc ces deux
              requêtes sont équivalentes (data est ignoré, consultez  la  sec-
              tion NOTES).

       PTRACE_PEEKUSER
              Lire  un mot à la position addr dans l'espace USER de l'observé,
              qui contient les registres et divers renseignements sur le  pro-
              cessus  (voir  <sys/user.h>). Le mot est renvoyée en résultat de
              ptrace(). En principe, l'adresse doit être alignée sur une fron-
              tière  de  mots,  bien  que  cela varie selon les architectures.
              Consultez la section NOTES. (data est ignoré, consultez la  sec-
              tion NOTES).

       PTRACE_POKETEXT, PTRACE_POKEDATA
              Copier  le  mot  data vers l'adresse addr de la mémoire de l'ob-
              servé. Comme pour PTRACE_PEEKTEXT et PTRACE_PEEKDATA,  ces  deux
              requêtes sont équivalentes.

       PTRACE_POKEUSER
              Copier  le  mot  data  vers l'adresse addr dans l'espace USER de
              l'observé. Comme pour PTRACE_PEEKUSER, les emplacements  doivent
              être  alignés  sur  une frontière de mot. Pour maintenir l'inté-
              grité du noyau, certaines modifications de la zone USER sont in-
              terdites.

       PTRACE_GETREGS, PTRACE_GETFPREGS
              Copier  les registres généraux ou du processeur en virgule flot-
              tante  de  l'observé,  vers  l'adresse  data  de  l'observateur.
              Consultez  <sys/user.h>  pour  les  détails sur le format de ces
              données (addr est ignoré). Remarquez que les systèmes SPARC  ont
              la signification de data et addr inversée, c'est-à-dire que data
              est ignoré et les registres sont  copiés  vers  l'adresse  addr.
              PTRACE_GETREGS  et  PTRACE_GETFPREGS  ne  sont  pas présents sur
              toutes les architectures.

       PTRACE_GETREGSET (depuis Linux 2.6.34)
              Lire les registres de l'observé. addr indique, de manière dépen-
              dante  de l'architecture, le type de registres à lire. NT_PRSTA-
              TUS (avec une valeur numérique de 1) a  pour  conséquence  habi-
              tuelle la lecture de registres généraux. Si le processeur a, par
              exemple, des registres en virgule flottante ou en  vecteur,  ils
              peuvent  être récupéré en configurant addr à la constante NT_foo
              correspondante. data pointe vers une struct  iovec,  qui  décrit
              l'emplacement  et  la  taille du tampon de destination. Le noyau
              modifie iov.len au retour  pour  indiquer  le  véritable  nombre
              d'octets renvoyés.

       PTRACE_SETREGS, PTRACE_SETFPREGS
              Modifier  les  registres  généraux  ou  du processeur en virgule
              flottante de l'observé, depuis l'adresse data de  l'observateur.
              Comme pour PTRACE_POKEUSER, certaines modifications de registres
              généraux pourraient être interdites (addr est ignoré). Remarquez
              que  les systèmes SPARC ont la signification de data et addr in-
              versée, c'est-à-dire que data est ignoré et les  registres  sont
              copiés depuis l'adresse addr. PTRACE_SETREGS et PTRACE_SETFPREGS
              ne sont pas présents sur toutes les architectures.

       PTRACE_SETREGSET (depuis Linux 2.6.34)
              Modifier les registres de l'observé. La signification de addr et
              data est analogue à PTRACE_GETREGSET.

       PTRACE_GETSIGINFO (depuis Linux 2.3.99-pre6)
              Récupérer  des renseignements sur le signal qui a provoqué l'ar-
              rêt. Pour ce faire, copier une  structure  siginfo_t  (consultez
              sigaction(2))  de  l'observé  à  l'adresse data de l'observateur
              (addr est ignoré).

       PTRACE_SETSIGINFO (depuis Linux 2.3.99-pre6)
              Définir les renseignements de signaux : copier une structure si-
              ginfo_t  de l'adresse data de l'observateur vers l'observé. Cela
              n'affecte que les signaux qui  auraient  dû  être  distribués  à
              l'observé  et ont été interceptés à cause de ptrace(). Différen-
              cier ces signaux normaux des signaux créés par ptrace() lui-même
              peut être délicat (addr est ignoré).

       PTRACE_PEEKSIGINFO (depuis Linux 3.10)
              Récupérer  les  structures  siginfo_t sans supprimer les signaux
              d’une  file  d’attente.   addr   pointe   vers   une   structure
              ptrace_peeksiginfo_args  qui indique la position ordinale à par-
              tir de laquelle la copie des signaux  devrait  commencer  et  le
              nombre  de  signaux  à copier. Les structures siginfo_t sont co-
              piées dans le tampon  pointé  par  data.  La  valeur  de  retour
              contient  le  nombre de signaux copiés (zéro indique qu’il n’y a
              pas de signal correspondant à la  position  ordinale  indiquée).
              Dans les structures siginfo renvoyées, le champ si_code contient
              des renseignements (__SI_CHLD, __SI_FAULT, etc.)  qui  sinon  ne
              sont pas exposés à l’espace utilisateur.

           struct ptrace_peeksiginfo_args {
               u64 off;    /* Position ordinale dans la file d’attente
                              où commencer la copie de signaux */
               u32 flags;  /* PTRACE_PEEKSIGINFO_SHARED ou 0 */
               s32 nr;     /* Nombre de signaux à copier */
           };

              Actuellement,  seul  l’attribut PTRACE_PEEKSIGINFO_SHARED permet
              de vider les signaux de la file de signaux par processus. Si cet
              attribut  n’est  pas défini, les signaux sont lus depuis la file
              par thread du thread indiqué.

       PTRACE_GETSIGMASK (depuis Linux 3.11)
              Placer une copie du masque des signaux bloqués  (consultez  sig-
              procmask(2))  dans le tampon pointé par data qui devrait être un
              pointeur vers  un  tampon  de  type  sigset_t.  L’argument  addr
              contient  la  taille du tampon pointé par data (c’est-à-dire si-
              zeof(sigset_t)).

       PTRACE_SETSIGMASK (depuis Linux 3.11)
              Modifier le  masque  des  signaux  bloqués  (consultez  sigproc-
              mask(2)) à la valeur indiquée dans le tampon pointé par data qui
              devrait être un pointeur vers un tampon de type sigset_t.  L’ar-
              gument  addr  contient  la  taille  du  tampon  pointé  par data
              (c’est-à-dire sizeof(sigset_t)).

       PTRACE_SETOPTIONS  (depuis  Linux 2.4.6,  consultez  les  remarques  de
       BOGUES)
              Définir  les  options de ptrace à partir de l'adresse data (addr
              est ignoré). data est interprété comme un masque d'options,  qui
              est construit à partir des attributs suivants.

              PTRACE_O_EXITKILL (depuis Linux 3.8)
                     Envoyer  un  signal  SIGKILL à l'observé si l'observateur
                     existe. Cet option est utile pour les gardiens ptrace qui
                     veulent  s'assurer  que  les  observés  ne peuvent jamais
                     échapper au contrôle de l'observateur.

              PTRACE_O_TRACECLONE (depuis Linux 2.5.46)
                     Arrêter l'observé au prochain clone(2) et commencer auto-
                     matiquement  à suivre le nouveau processus cloné, qui dé-
                     marrera avec un signal SIGSTOP, ou  PTRACE_EVENT_STOP  si
                     PTRACE_SEIZE est utilisé. Un waitpid(2) par l'observateur
                     renverra une valeur status comme

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

                     Le PID du  nouveau  processus  peut  être  récupéré  avec
                     PTRACE_GETEVENTMSG.

                     Cette  option  peut  ne  pas  intercepter tous les appels
                     clone(2). Si l'observé appelle clone(2)  avec  l'attribut
                     CLONE_VFORK,    PTRACE_EVENT_VFORK    sera    envoyé   si
                     PTRACE_O_TRACEVFORK est utilisé. Sinon, si l'observé  ap-
                     pelle  clone(2) avec SIGCHLD comme signal de terminaison,
                     PTRACE_EVENT_FORK sera envoyé si  PTRACE_O_TRACEFORK  est
                     utilisé.

              PTRACE_O_TRACEEXEC (depuis Linux 2.5.46)
                     Arrêter  l'observé  au  prochain execve(2). Un waitpid(2)
                     par l'observateur renverra une valeur status comme

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

                     Si le thread en cours d'exécution n'est pas un leader  de
                     groupe  de threads, l'identifiant de thread est réinitia-
                     lisé à l'identifiant du leader de groupe de threads avant
                     cet  arrêt.  Depuis  Linux 3.0, le premier identifiant de
                     thread peut être récupéré avec PTRACE_GETEVENTMSG.

              PTRACE_O_TRACEEXIT (depuis Linux 2.5.60)
                     Arrêter l'observé à la  terminaison.  Un  waitpid(2)  par
                     l'observateur renverra une valeur status comme

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

                     L'état  de  fin  de  l'observé  peut  être  récupéré avec
                     PTRACE_GETEVENTMSG.

                     L'observé est arrêté tôt dans la terminaison  du  proces-
                     sus,  alors  que les registres sont toujours disponibles,
                     ce qui permet au processus utilisant ptrace() de voir  où
                     la  terminaison s'est produite, alors que la notification
                     de terminaison normale a lieu à la fin de cette terminai-
                     son. Même si le contexte est disponible, l'observateur ne
                     peut pas empêcher la terminaison à ce moment là.

              PTRACE_O_TRACEFORK (depuis Linux 2.5.46)
                     Arrêter l'observé au prochain fork(2) et commencer  auto-
                     matiquement  à  suivre le nouveau processus créé, qui dé-
                     marrera avec un signal SIGSTOP, ou  PTRACE_EVENT_STOP  si
                     PTRACE_SEIZE est utilisé. Un waitpid(2) par l'observateur
                     renverra une valeur status comme

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

                     Le PID du  nouveau  processus  peut  être  récupéré  avec
                     PTRACE_GETEVENTMSG.

              PTRACE_O_TRACESYSGOOD (depuis Linux 2.4.6)
                     Lors  des  interceptions  d'appel système, positionner le
                     bit 7 sur le numéro  de  signal  (envoyer  SIGTRAP|0x80).
                     Cela facilite pour l'observateur la distinction entre les
                     interceptions normales et celles provoquées par un  appel
                     système.

              PTRACE_O_TRACEVFORK (depuis Linux 2.5.46)
                     Arrêter l'observé au prochain vfork(2) et commencer auto-
                     matiquement à suivre le nouveau processus créé,  qui  dé-
                     marrera  avec  un signal SIGSTOP, ou PTRACE_EVENT_STOP si
                     PTRACE_SEIZE est utilisé. Un waitpid(2) par l'observateur
                     renverra une valeur status comme

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

                     Le  PID  du  nouveau  processus  peut  être récupéré avec
                     PTRACE_GETEVENTMSG.

              PTRACE_O_TRACEVFORKDONE (depuis Linux 2.5.60)
                     Arrêter l'observé à la fin du prochain vfork(2). Un wait-
                     pid(2) par l'observateur renverra une valeur status comme

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

                     Le  PID  du  nouveau processus peut (depuis Linux 2.6.18)
                     être récupéré avec PTRACE_GETEVENTMSG.

              PTRACE_O_TRACESECCOMP (depuis Linux 3.5)
                     Arrêter l'observé quand une  règle  SECCOMP_RET_TRACE  de
                     seccomp(2)  est  déclenchée. Un waitpid(2) par l'observa-
                     teur renverra une valeur status comme

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

                     Si cela entraîne un arrêt PTRACE_EVENT, c'est  équivalent
                     à  un  arrêt-entrée-appel-système. Pour des détails, voir
                     la remarque sur PTRACE_EVENT_SECCOMP ci-dessous. Les don-
                     nées du message de l'événement seccomp (issues de la par-
                     tie SECCOMP_RET_DATA  de  la  règle  du  filtre  seccomp)
                     peuvent être récupérées avec PTRACE_GETEVENTMSG.

              PTRACE_O_SUSPEND_SECCOMP (depuis Linux 4.3)
                     Suspendre  les  protections  seccomp  de  l'observé. Cela
                     s'applique quel que soit le mode  et  peut  être  utilisé
                     lorsque l'observé n'a pas encore installé de filtres sec-
                     comp. Cela veut  dire  qu'un  cas  d'utilisation  valable
                     consiste à suspendre les protections seccomp d'un observé
                     avant qu'elles ne soient installées par l'observé,  lais-
                     ser l'observé installer les filtres et vider cet attribut
                     quand les filtres doivent être réactivés.  La  définition
                     de  cette  option implique que l'observateur ait la capa-
                     cité CAP_SYS_ADMIN, n'ait pas de protection seccomp  ins-
                     tallée  et  n'ait  pas  de PTRACE_O_SUSPEND_SECCOMP posi-
                     tionné sur lui-même.

       PTRACE_GETEVENTMSG (depuis Linux 2.5.46)
              Récupérer un message (dans un unsigned long) concernant l'événe-
              ment  ptrace qui vient d'arriver, en le plaçant à l'adresse data
              de l'observateur. Pour PTRACE_EVENT_EXIT, il s'agit du  code  de
              retour de l'observé. Pour PTRACE_EVENT_FORK, PTRACE_EVENT_VFORK,
              PTRACE_EVENT_VFORK_DONE et PTRACE_EVENT_CLONE, il s'agit du  PID
              du  nouveau  processus. Pour PTRACE_EVENT_SECCOMP, il s'agit des
              SECCOMP_RET_DATA du filtre seccomp(2) associées à la  règle  dé-
              clenchée (addr est ignorée).

       PTRACE_CONT
              Redémarrer  l'observé arrêté. Si data est non nul, il est inter-
              prété comme un numéro de signal à distribuer à l'observé ; sinon
              aucun signal n'est distribué. L'observateur peut ainsi contrôler
              si un signal envoyé à l'observé doit lui être distribué  ou  non
              (addr est ignoré).

       PTRACE_SYSCALL, PTRACE_SINGLESTEP
              Redémarrer  l'observé  arrêté  comme  pour  PTRACE_CONT, mais en
              s'arrangeant pour qu'il soit arrêté à  la  prochaine  entrée  ou
              sortie  d'un  appel  système, ou après la prochaine instruction,
              respectivement (l'observé sera aussi arrêté par  l'arrivée  d'un
              signal).  Du  point  de vue de l'observateur, l'observé semblera
              être arrêté par SIGTRAP. Ainsi, pour PTRACE_SYSCALL  l'idée  est
              d'inspecter  les  arguments  de l'appel système au premier arrêt
              puis de faire un autre PTRACE_SYSCALL et d'inspecter  la  valeur
              de  retour  au  second  arrêt.  Le paramètre data est interprété
              comme pour PTRACE_CONT (addr est ignoré).

       PTRACE_SET_SYSCALL (depuis Linux 2.6.16)
              Lorsqu'il est en arrêt-entrée-appel-système, passer le numéro de
              l'appel  système qui va être exécuté à celui indiqué dans le pa-
              ramètre data. Le paramètre addr est ignoré. Cette requête  n'est
              actuellement prise en charge que sur arm (et arm64, quoique uni-
              quement à des fins de rétrocompatibilité), mais la  plupart  des
              autres architectures ont d'autres moyens de faire cela (en géné-
              ral en modifiant le registre qui a passé l'appel système au code
              au niveau de l'utilisateur).

       PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP (depuis Linux 2.6.14)
              Pour  PTRACE_SYSEMU,  continuer  puis s'arrêter lors du prochain
              appel système, qui ne sera pas exécuté.  Voir  la  documentation
              des  syscall-stops  ci-dessous.  Pour  PTRACE_SYSEMU_SINGLESTEP,
              faire la même chose, mais exécuter pas à pas s'il ne s'agit  pas
              d'un  appel  système.  Cette  fonction est utilisée par des pro-
              grammes comme User Mode Linux, qui veulent émuler tous  les  ap-
              pels  système  de  l'observé.  Le  paramètre data est interprété
              comme pour PTRACE_CONT. L'argument addr est ignoré. Ces requêtes
              ne sont pour l'instant disponibles que sur x86.

       PTRACE_LISTEN (depuis Linux 3.4)
              Redémarrer  l'observé arrêté, mais en l'empêchant de s'exécuter.
              L'état résultant de l'observé est similaire a celui d'un proces-
              sus  qui  a été arrêté par un SIGSTOP (ou autre signal d'arrêt).
              Consultez la sous-section Arrêt-groupe pour  des  renseignements
              supplémentaires.  PTRACE_LISTEN ne fonctionne que sur les obser-
              vés attachés par PTRACE_SEIZE.

       PTRACE_KILL
              Envoyer à l'observé un signal SIGKILL pour le terminer (addr  et
              data sont ignorés).

              Cette opération est obsolète, ne l'utilisez pas. À la place, en-
              voyez un SIGKILL directement en utilisant kill(2) ou  tgkill(2).
              Le  problème  avec PTRACE_KILL est qu'il nécessite que l'observé
              soit en arrêt-distribution-signal, sinon cela risque de  ne  pas
              fonctionner (c'est-à-dire risque de se terminer avec succès sans
              tuer l'observé). En revanche, envoyer SIGKILL directement  n'est
              pas concerné par cette limite.

       PTRACE_INTERRUPT (depuis Linux 3.4)
              Arrêter  un observé. Si l’observé est en cours d’exécution ou en
              sommeil dans l’espace utilisateur et que PTRACE_SYSCALL est  ef-
              fectif,  l’appel  système  est  interrompu et l'arrêt-sortie-ap-
              pel-système est signalé (l’appel système  interrompu  est  redé-
              marré  quand  l’observé  est redémarré). Si l’observé avait déjà
              été arrêté par un signal et que PTRACE_LISTEN lui avait été  en-
              voyé, l’observé s’arrête avec PTRACE_EVENT_STOP et WSTOPSIG(sta-
              tus) renvoie le signal d’arrêt.  Si  n’importe  quel  autre  ar-
              rêt-ptrace est créé en même temps (par exemple, si un signal est
              envoyé à l’observé), cet arrêt-ptrace arrive. Si rien de ce  qui
              précède  ne  s’applique  (par  exemple si l’observé est en cours
              d’exécution   en   espace   utilisateur),   il   s’arrête   avec
              PTRACE_EVENT_STOP  avec  WSTOPSIG(status) == SIGTRAP. PTRACE_IN-
              TERRUPT  ne  fonctionne  que  sur  les  observés  attachés   par
              PTRACE_SEIZE.

       PTRACE_ATTACH
              Attacher  le  processus numéro pid, pour le suivre. L'observé va
              recevoir un SIGSTOP, mais il ne sera peut-être pas  arrêté  tout
              de  suite, utilisez waitid(2) pour attendre son arrêt. Consultez
              la sous-section Attachement et détachement pour obtenir de  plus
              amples renseignements (addr et data sont ignorés).

              Le  droit d'effectuer un PTRACE_ATTACH est géré par la vérifica-
              tion PTRACE_MODE_ATTACH_REALCREDS du mode  d'accès  de  ptrace ;
              voir ci-dessous.

       PTRACE_SEIZE (depuis Linux 3.4)
              Attacher  au  processus indiqué dans pid, en faire un observé du
              processus appelant. Contrairement à PTRACE_ATTACH,  PTRACE_SEIZE
              n'arrête  pas  le  processus. Les arrêts-groupe sont signalés en
              tant que PTRACE_EVENT_STOP et WSTOPSIG(status) renvoie le signal
              d'arrêt.    Les    enfants    automatiquement    attachés   avec
              PTRACE_EVENT_STOP et WSTOPSIG(status) renvoient SIGTRAP au  lieu
              de  recevoir  un signal SIGSTOP. execve(2) n'envoie pas d'autres
              SIGTRAP. Seul un processus PTRACE_SEIZEé peut accepter des  com-
              mandes PTRACE_INTERRUPT et PTRACE_LISTEN. Le comportement « sei-
              zed » qui vient d'être décrit est récupéré par les enfants auto-
              matiquement    attachés    en    utilisant   PTRACE_O_TRACEFORK,
              PTRACE_O_TRACEVFORK et PTRACE_O_TRACECLONE. addr  doit  être  de
              zéro.  data contient un masque de bit des options ptrace à acti-
              ver immédiatement.

              Le droit d'effectuer un PTRACE_SEIZE est géré par une  vérifica-
              tion  PTRACE_MODE_ATTACH_REALCREDS du mode d'accès ptrace ; voir
              ci-dessous.

       PTRACE_SECCOMP_GET_FILTER (depuis Linux 4.4)
              Cette opération autorise l'observateur à vider les  filtres  BPF
              classiques de l'observé.

              addr  est  un  entier  indiquant  l'index  du filtre à vider. Le
              filtre le plus récemment installé a le numéro d'index 0. Si addr
              est  supérieur  aux  numéros  des filtres installés, l'opération
              échoue avec l'erreur ENOENT.

              data est soit un pointeur vers un tableau struct sock_filter as-
              sez  grand  pour  stocker le programme BPF, soit NULL si le pro-
              gramme ne va pas être stocké.

              En cas de succès, le code de retour est le nombre d'instructions
              du  programme  BPF.  Si  data était NULL, ce code de retour peut
              être utilisé pour dimensionner correctement  le  tableau  struct
              sock_filter passé dans un appel ultérieur.

              Cette  opération  échoue  avec l'erreur EACCES si l'appelant n'a
              pas la capacité CAP_SYS_ADMIN ou s'il est en mode seccomp filtré
              ou  restreint.  Si  le  filtre  auquel renvoie addr n'est pas un
              filtre BPF classique, l'opération échoue avec l'erreur  EMEDIUM-
              TYPE.

              Cette opération n'est disponible que si le noyau a été configuré
              avec les options CONFIG_SECCOMP_FILTER et CONFIG_CHECKPOINT_RES-
              TORE.

       PTRACE_DETACH
              Relancer  l'observé  arrêté comme avec PTRACE_CONT, mais en com-
              mençant par s'en détacher. Sous Linux un observé peut être déta-
              ché  ainsi  quelque  soit  la  méthode employée pour démarrer le
              suivi (addr est ignoré).

       PTRACE_GET_THREAD_AREA (depuis Linux 2.6.0)
              Cette    opération    effectue    une    tâche    identique    à
              get_thread_area(2). Elle lit l'entrée TLS dans le GDT dont l'in-
              dex est donné dans addr, mettant une copie de l'entrée  dans  la
              struct  user_desc  vers  laquelle  pointe  data (contrairement à
              get_thread_area(2), entry_number  de  la  struct  user_desc  est
              ignorée).

       PTRACE_SET_THREAD_AREA (depuis Linux 2.6.0)
              Cette  opération  effectue la même tâche que set_thread_area(2).
              Elle positionne l'entrée TLS dans le GDT dont l'index est  donné
              dans  addr, en lui affectant les données fournies dans la struct
              user_desc   vers   laquelle   pointe   data   (contrairement   à
              set_thread_area(2),  entry_number  de  la  struct  user_desc est
              ignorée ; autrement dit, cette opération de ptrace ne  peut  pas
              être utilisée pour affecter une entrée TLS libre).

       PTRACE_GET_SYSCALL_INFO (depuis Linux 5.3)
              Récupérer  des  informations  sur l'appel système qui a provoqué
              l'arrêt. Les informations sont placées dans le tampon  vers  le-
              quel pointe le paramètre data, lequel doit être un pointeur vers
              un tampon de type struct ptrace_syscall_info. Le paramètre  addr
              contient  la  taille  du  tampon vers lequel pointe le paramètre
              data (à savoir sizeof(struct ptrace_syscall_info)). Le  code  de
              retour  contient le nombre d'octets que le noyau peut écrire. Si
              la taille des données que le noyau doit écrire dépasse celle in-
              diquée  par  le paramètre addr, les données de sortie sont tron-
              quées.

              La structure ptrace_syscall_info contient les champs suivants :

                  struct ptrace_syscall_info {
                      __u8 op;        /* Type d'appel système d'arrêt */
                      __u32 arch;     /* Valeur AUDIT_ARCH_* ; voir seccomp(2) */
                      __u64 instruction_pointer; /* Pointeur vers l'instruction du processeur */
                      __u64 stack_pointer;    /* Pointeur vers la pile du processeur */
                      union {
                          struct {    /* op == PTRACE_SYSCALL_INFO_ENTRY */
                              __u64 nr;       /* Numéro de l'appel système */
                              __u64 args[6];  /* Paramètres de l'appel système */
                          } entry;
                          struct {    /* op == PTRACE_SYSCALL_INFO_EXIT */
                              __s64 rval;     /* Code de retour de l'appel système */
                              __u8 is_error;  /* Attribut d'erreur de l'appel système ;
                                                 Booléen : rval contient-il
                                                 un code d'erreur (-ERRCODE) ou
                                                 un code de retour de non erreur ? */
                          } exit;
                          struct {    /* op == PTRACE_SYSCALL_INFO_SECCOMP */
                              __u64 nr;       /* Numéro de l'appel système */
                              __u64 args[6];  /* Paramètres de l'appel système */
                              __u32 ret_data; /* Partie SECCOMP_RET_DATA de la valeur
                                                 de retour de SECCOMP_RET_TRACE */
                          } seccomp;
                      };
                  };

              Les champs op, arch, instruction_pointer et  stack_pointer  sont
              définis  pour tous les types d'arrêts de l'appel système ptrace.
              Le reste de la structure est une union ; on ne doit lire que les
              champs significatifs pour le type d'arrêt de l'appel système in-
              diqué par le champ op.

              Le champ op prend une des valeurs suivantes (définies dans  <li-
              nux/ptrace.h>),  indiquant  le type d'arrêt qui s'est produit et
              la partie remplie de l'union :

              PTRACE_SYSCALL_INFO_ENTRY
                     Le composant entry de l'union contient  des  informations
                     liées à un arrêt d'entrée appel système.

              PTRACE_SYSCALL_INFO_EXIT
                     Le  composant  exit  de l'union contient des informations
                     sur un arrêt de sortie d'appel système.

              PTRACE_SYSCALL_INFO_SECCOMP
                     Le composant seccomp de l'union contient des informations
                     concernant un arrêt PTRACE_EVENT_SECCOMP.

              PTRACE_SYSCALL_INFO_NONE
                     Aucun  composant  de  l'union  ne contient d'informations
                     pertinentes.

   Mort sous ptrace
       Quand un processus (éventuellement multithreadé) reçoit un signal  pour
       le  tuer (un dont la disposition est configurée à SIG_DFL et dont l'ac-
       tion par défaut est de tuer le processus), tous  les  threads  se  ter-
       minent.  Chaque  observé  signale sa mort à son ou ses observateurs. La
       notification de cet événement est distribuée par waitpid(2).

       Remarquez que le signal tueur  provoquera  d'abord  un  arrêt-distribu-
       tion-signal  (sur un seul observé) et, seulement après être injecté par
       l'observateur (ou après être envoyé à un thread qui n'est  pas  suivi),
       la  mort du signal arrivera sur tous les observés d'un processus multi-
       threadé (le terme « arrêt-distribution-signal » est expliqué plus bas).

       SIGKILL ne génère pas d'arrêt-distribution-signal et  l'observateur  ne
       peut  par  conséquent  pas le supprimer. SIGKILL tue même à l'intérieur
       des appels systèmes (arrêt-sortie-appel-système n'est pas créé avant la
       mort  par SIGKILL). L'effet direct est que SIGKILL tue toujours le pro-
       cessus (tout ses threads), même si certains threads du  processus  sont
       suivis avec ptrace.

       Quand l'observé appelle _exit(2), il signale sa mort à son observateur.
       Les autres threads ne sont pas concernés.

       Quand n'importe quel thread exécute exit_group(2), tous les observés de
       son groupe de threads signalent leur mort à leur observateur.

       Si  l'option  PTRACE_O_TRACEEXIT est active, PTRACE_EVENT_EXIT arrivera
       avant la mort réelle. Cela s'applique aux  terminaisons  avec  exit(2),
       exit_group(2) et aux morts de signal (sauf SIGKILL, selon la version du
       noyau ; voir les BOGUES ci-dessous), et lorsque les  threads  sont  dé-
       truits par execve(2) dans un processus multithreadé.

       L'observateur  ne  peut pas assumer que l'observé arrêté-ptrace existe.
       L'observé risque de mourir  avant  d'être  arrêté  dans  plusieurs  cas
       (comme  avec  SIGKILL). Par conséquent, le tracé doit être préparé pour
       traiter une erreur ESRCH sur n'importe quelle opération ptrace. Malheu-
       reusement,  la  même erreur est renvoyée si l'observé existe mais n'est
       pas arrêté-ptrace (pour les commandes qui nécessitent  un  observé  ar-
       rêté),  ou  s'il  n'est pas suivi par le processus qui a envoyé l'appel
       ptrace. L'observateur doit garder une trace  de  l'état  arrêté  ou  en
       fonctionnement  de  l'observé,  et  interpréter ESRCH comme « l'observé
       s'est achevé de manière inattendue » seulement s'il sait que  l'observé
       est  effectivement entré en arrêt-ptrace. Remarquez qu'il n'est pas ga-
       ranti que waitpid(WNOHANG) signale de façon fiable l'état  de  mort  de
       l'observé si une opération ptrace renvoie ESRCH. waitpid(WNOHANG) pour-
       rait plutôt renvoyer 0. Autrement dit, l'observé pourrait « ne pas être
       encore mort », mais déjà refuser des requêtes ptrace.

       L'observateur  ne  peut pas assumer que l'observé finit toujours sa vie
       en signalant WIFEXITED(status) ou WIFSIGNALED(status) ;  dans  certains
       cas  ça  n'arrive  pas. Par exemple si un thread différent du leader de
       groupe de threads fait un execve(2), il disparaît ;  son  PID  ne  sera
       plus jamais vu, tous les arrêts suivants de ptrace seront signalés sous
       le PID du leader de groupe de threads.

   États arrêtés
       Deux états existent pour un observé : en cours d'exécution ou  à  l'ar-
       rêt. Du point de vue de ptrace, un observé qui est bloqué dans un appel
       système (comme read(2),  pause(2), etc.)  est  néanmoins  considéré  en
       cours  d’exécution,  même  si  l’observé  est  bloqué depuis longtemps.
       L’état de l’observé après PTRACE_LISTEN est en quelque sorte  une  zone
       d’ombre :  il n’est dans aucun arrêt-ptrace (les commandes ptrace n’au-
       ront aucun effet sur lui et  il  distribuera  des  notifications  wait-
       pid(2)),  mais  il pourrait aussi être considéré « arrêté » parce qu’il
       n’est pas en train d’exécuter des instructions (pas  de  programmation)
       et,  s’il était en arrêt-groupe avant PTRACE_LISTEN, il ne répondra pas
       aux signaux avant de recevoir SIGCONT.

       De nombreuses sortes d'états sont possibles quand l'observé est arrêté,
       et les discussions dans ptrace sont souvent confondues. Par conséquent,
       l'utilisation de termes précis est importante.

       Dans cette page de manuel, tous les états d'arrêt dans  lesquels  l'ob-
       servé  est  prêt  à accepter des commandes ptrace de l'observateur sont
       appelés arrêt-ptrace. Les arrêts-ptrace peuvent ensuite être sous-divi-
       sés   en   arrêt-distribution-signal,   arrêt-groupe,  arrêt-appel-sys-
       tème, arrêt-PTRACE_EVENT, etc. Ces états d'arrêt sont décrits en détail
       ci-dessous.

       Lorsque  l'observé en cours d'exécution entre en arrêt-ptrace, il avise
       son observateur en utilisant waitpid(2) (ou un des autres  appels  sys-
       tème « wait »). La plupart de cette page de manuel suppose que l'obser-
       vateur attend avec :

           pid = waitpid(pid_ou_moins_1, &status, __WALL);

       Les observés arrêtés-ptrace sont signalés comme renvoyés  avec  un  pid
       strictement positif et WIFSTOPPED(status) vrai.

       L'attribut  __WALL  ne  contient pas les attributs WSTOPPED et WEXITED,
       mais implique leur fonctionnalité.

       La configuration de l'attribut WCONTINUED en appelant waitpid(2)  n'est
       pas  conseillée : l'état « exécuté » est relatif au processus et l'uti-
       liser peut embrouiller le vrai parent de l'observé.

       Utiliser l'attribut WNOHANG pourrait forcer  waitpid(2)  à  renvoyer  0
       (« aucun  résultat d'attente encore disponible ») même si l'observateur
       sait qu'il devrait y avoir une notification. Exemple :

           errno = 0;
           ptrace(PTRACE_CONT, pid, 0L, 0L);
           if (errno == ESRCH) {
               /* l'observé est mort */
               r = waitpid(tracee, &status, __WALL | WNOHANG);
               /* r peut encore valoir 0 ici ! */
           }

       Les sortes d'arrêts-ptrace suivants existent :  arrêts-distribution-si-
       gnal,  arrêts-groupe,  arrêts PTRACE_EVENT et arrêts-appel-système. Ils
       sont signalés par waitpid(2) avec WIFSTOPPED(status) vrai. Ils  peuvent
       être distingués en examinant la valeur status>>8, et en cas d'ambiguïté
       dans cette valeur, en faisant une requête PTRACE_GETSIGINFO (remarque :
       la  macro  WSTOPSIG(status) ne peut pas être utilisée pour réaliser cet
       examen, car elle renvoie la valeur (status>>8) & 0xff.)

   Arrêt-distribution-signal
       Quand un processus (éventuellement multithreadé) reçoit n'importe  quel
       signal  sauf SIGKILL, le noyau choisi un thread arbitraire pour traiter
       le signal (si le signal est créé avec tgill(2), le  thread  cible  peut
       être  explicitement choisi par l'appelant). Si le thread choisi est ob-
       servé, il entre en arrêt-distribution-signal. À ce moment là, le signal
       n'est  pas  encore  distribué  au  processus, et peut être supprimé par
       l'observateur. Si l'observateur ne supprime pas le signal, il passe  le
       signal  à  l'observé  lors  de  la  requête  suivante de redémarrage de
       ptrace. Cette deuxième étape de distribution de signal est appelée  in-
       jection de signal dans cette page de manuel. Remarquez que si le signal
       est bloqué, l'arrêt-distribution-signal n'arrive pas avant que  le  si-
       gnal  soit  débloqué,  à l'exception habituelle que SIGSTOP ne peut pas
       être bloqué.

       L'arrêt-distribution-signal est respecté  par  l'observateur  tant  que
       waitpid(2)  retourne  avec WIFSTOPPED(status) vrai, avec le signal ren-
       voyé par WSTOPSIG(status). Si le signal est SIGTRAP, cela pourrait être
       un  arrêt-ptrace  de  nature  différente ;  consultez  les sections Ar-
       rêts-appel-système et execve(2) sous ptrace plus bas  pour  obtenir  de
       plus  amples précisions. Si WSTOPSIG(status) renvoie un signal d'arrêt,
       cela pourrait être un arrêt-groupe ; voir ci-dessous.

   Injection et suppression de signal
       Après un arrêt-distribution-signal respecté par l'observateur, l'obser-
       vateur devrait redémarrer l'observé avec l'appel

           ptrace(PTRACE_restart, pid, 0, sig)

       où  PTRACE_restart  est  une des requêtes ptrace de redémarrage. Si sig
       est 0, alors aucun signal n'est distribué. Sinon,  le  signal  sig  est
       distribué.  Cette  opération est appelée injection de signal dans cette
       page de manuel, pour la distinguer de l'arrêt-distribution-signal.

       La valeur de sig peut être différente de  celle  de  WSTOPSIG(status) :
       l'observateur peut provoquer l'injection d'un autre signal.

       Remarquez  qu'un  signal supprimé provoque toujours un retour prématuré
       des appels système. Dans ce cas, les appels système seront redémarrés :
       l'observateur forcera l'observé à réexécuter l'appel système interrompu
       (ou l'appel système restart_syscall(2) pour les quelques appels système
       qui  utilisent un autre mécanisme de redémarrage) si l'observateur uti-
       lise PTRACE_SYSCALL. Même les appels système  (comme  poll(2))  qui  ne
       sont  pas  redémarrables  après le signal sont redémarrés après la sup-
       pression du signal ; cependant, des bogues du noyau  existent  et  cer-
       tains  appels  système  échouent avec EINTR même si aucun signal obser-
       vable n'est injecté dans l'observé.

       Lors du redémarrage des  commandes  ptrace  émises  dans  d'autres  ar-
       rêts-ptrace  qu'arrêt-distribution-signal,  l'injection de signal n'est
       pas garantie, même si sig est non nul. Aucune erreur  n'est  signalée ;
       un  sig  non  nul  risque simplement d'être ignoré. Les utilisateurs de
       ptrace ne devraient pas essayer de « créer un nouveau signal » de cette
       façon : utilisez plutôt tgkill(2).

       Le  fait  que des requêtes d'injection de signal puissent être ignorées
       lors du redémarrage de l'observé après des arrêts ptrace  qui  ne  sont
       pas des arrêts-distribution-signal est une source de confusion pour les
       utilisateurs de ptrace. Un scénario typique est que  l'observateur  re-
       marque  un arrêt-groupe, le confonde avec un arrêt-distribution-signal,
       et redémarre l'observé avec

           ptrace(PTRACE_restart, pid, 0, stopsig)

       dans le but d'injecter stopsig, mais stopsig sera ignoré  et  l'observé
       continuera de fonctionner.

       Le  signal  SIGCONT a pour effet de bord de réveiller (tous les threads
       d')un processus arrêté-groupe. Cet effet de bord arrive  avant  un  ar-
       rêt-distribution-signal.  L'observateur ne peut pas supprimer cet effet
       de bord (il ne peut que supprimer  l'injection  de  signal,  qui  force
       seulement  le  gestionnaire de SIGCONT à ne pas être exécuté dans l'ob-
       servé, si un gestionnaire de ce type est installé). En fait, le  réveil
       depuis  un  arrêt-groupe  pourrait  être  suivi  par un arrêt-distribu-
       tion-signal pour le ou les signaux différents de SIGCONT, s'ils étaient
       en  attente quand SIGCONT a été distribué. Autrement dit, SIGCONT pour-
       rait ne pas être le premier signal remarqué par l'observé  après  avoir
       été envoyé.

       L'arrêt  de signaux force (tous les threads d')un processus à entrer en
       arrêt-groupe. Cet effet de bord arrive après une injection  de  signal,
       et peut par conséquent être supprimé par l'observateur.

       Sous  Linux 2.4  et les versions précédentes, le signal SIGSTOP ne pou-
       vait pas être injecté.

       PTRACE_GETSIGINFO peut être utilisé pour récupérer  une  structure  si-
       ginfo_t  qui correspond au signal distribué. PTRACE_SETSIGINFO pourrait
       être utilisé pour le modifier. Si PTRACE_SETSIGINFO a été utilisé  pour
       modifier  siginfo_t,  le  champ si_signo et le paramètre sig de la com-
       mande de redémarrage doivent correspondre, sinon le résultat est  indé-
       fini.

   Arrêt-groupe
       Quand un processus (éventuellement multithreadé) reçoit un signal d'ar-
       rêt, tous les threads s'arrêtent. Si certains threads sont suivis,  ils
       entrent  en  arrêt-groupe.  Remarquez  que le signal d'arrêt provoquera
       d'abord un arrêt-distribution-signal (sur un seul observé)  et,  seule-
       ment  après avoir été injecté par l'observateur (ou après avoir été en-
       voyé à un thread qui n'est pas suivi), l'arrêt-groupe sera  initié  sur
       tous  les  observés d'un processus multithreadé. Comme d'habitude, tous
       les observés signalent leur  arrêt-groupe  séparément  à  l'observateur
       correspondant.

       L'arrêt-groupe  est  respecté par l'observateur tant que waitpid(2) re-
       tourne avec WIFSTOPPED(status) vrai, avec le signal d'arrêt  disponible
       par  l'intermédiaire  de WSTOPSIG(status). Le même résultat est renvoyé
       par  d'autres  classes  d'arrêts-ptrace,  par  conséquent  la   méthode
       conseillée est de réaliser l'appel

           ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo)

       L'appel  peut être évité si le signal n'est pas SIGSTOP, SIGTSTP, SIGT-
       TIN ou SIGTTOU ; seuls ces quatre signaux sont des signaux d'arrêt.  Si
       l'observateur  voit  autre  chose, ce ne peut pas être un arrêt-groupe.
       Sinon, l'observateur doit appeler PTRACE_GETSIGINFO.  Si  PTRACE_GETSI-
       GINFO  échoue  avec  EINVAL, alors c'est définitivement un arrêt-groupe
       (d'autres codes d'échec sont possibles, comme ESRCH (« pas de processus
       de ce type ») si un SIGKILL a tué l'observé).

       Si  l’observé  était attaché en utilisant PTRACE_SEIZE, un arrêt-groupe
       est indiqué par PTRACE_EVENT_STOP :  status>>16  ==  PTRACE_EVENT_STOP.
       Cela  permet  la  détection  d’arrêts-groupe  sans  nécessiter  d’appel
       PTRACE_GETSIGINFO supplémentaire.

       Depuis Linux 2.6.38, après que l'observateur  a  vu  l'arrêt-ptrace  de
       l'observé  et  jusqu'à  ce  qu'il  le redémarre ou le tue, l'observé ne
       fonctionnera pas, et n'enverra pas de notification (sauf mort par  SIG-
       KILL)  à l'observateur, même si l'observateur entre dans un autre appel
       waitpid(2).

       Le comportement du noyau décrit dans le paragraphe  précédent  pose  un
       problème avec la gestion transparente de signaux d'arrêt. Si l'observa-
       teur redémarre l'observé après un arrêt-groupe, le signal  d'arrêt  est
       effectivement ignoré — l'observé ne reste pas arrêté, il fonctionne. Si
       l'observateur ne redémarre pas l'observé avant d'entrer  dans  le  pro-
       chain waitpid(2), les signaux SIGCONT suivants ne seront pas signalés à
       l'observateur ; cela pourrait forcer des signaux SIGCONT  à  être  sans
       effet sur l'observé.

       Depuis  Linux 3.4, une méthode permet d'éviter ce problème : à la place
       de PTRACE_CONT, une commande PTRACE_LISTEN peut être utilisée pour  re-
       démarrer  un observé de façon à ce qu'il ne s'exécute pas, mais attende
       un nouvel événement qu'il peut signaler à l'aide de  waitpid(2)  (comme
       s'il était redémarré par un SIGCONT).

   Arrêts PTRACE_EVENT
       Si  l'observateur configure des options PTRACE_O_TRACE_*, l'observé en-
       trera en arrêts-ptrace appelés arrêts PTRACE_EVENT.

       Les arrêts PTRACE_EVENT sont respectés par  l'observateur  pendant  que
       waitpid(2)  renvoie  WIFSTOPPED(status) et que WSTOPSIG(status) renvoie
       SIGTRAP (ou pour PTRACE_EVENT_STOP, renvoie le signal d'arrêt si  l'ob-
       servé est dans un arrêt de groupe). Un bit supplémentaire est configuré
       dans l'octet le plus haut du mot d'état : la valeur status>>8 sera

           ((PTRACE_EVENT_foo<<8) | SIGTRAP).

       Les événements suivants existent.

       PTRACE_EVENT_VFORK
              Arrêt avant de revenir de vfork(2) ou clone(2)  avec  l'attribut
              CLONE_VFORK.  Quand  l'observé  est continué après cet arrêt, il
              attendra une sortie ou exécution de l'enfant avant de  continuer
              son  exécution  (autrement  dit,  le  comportement  normal  avec
              vfork(2)).

       PTRACE_EVENT_FORK
              Arrêt avant de revenir de fork(2) ou clone(2) avec le signal  de
              sortie configuré à SIGCHLD.

       PTRACE_EVENT_CLONE
              Arrêt avant de revenir de clone(2).

       PTRACE_EVENT_VFORK_DONE
              Arrêt  avant  de revenir de vfork(2) ou clone(2) avec l'attribut
              CLONE_VFORK, mais après que l'enfant a débloqué son observé  par
              sortie ou exécution.

       Pour les quatre arrêts décrits ci-dessus, l'arrêt arrive dans le parent
       (c'est-à-dire l'observé), pas dans le nouveau thread créé. PTRACE_GETE-
       VENTMSG permet de récupérer l'identifiant du nouveau thread.

       PTRACE_EVENT_EXEC
              Arrêt  avant le retour d'execve(2). Depuis Linux 3.0, PTRACE_GE-
              TEVENTMSG renvoie le premier identifiant de thread.

       PTRACE_EVENT_EXIT
              Arrêt avant la sortie (y compris la mort depuis  exit_group(2)),
              la  mort  du signal ou la sortie provoquée par execve(2) dans un
              processus multithreadé.  PTRACE_GETEVENTMSG  renvoie  l'état  de
              sortie.  Les  registres  peuvent  être examinés (contrairement à
              quand une « vraie » sortie arrive). L'observé est  toujours  ac-
              tif ;  il a besoin de PTRACE_CONT ou PTRACE_DETACH pour terminer
              sa sortie.

       PTRACE_EVENT_STOP
              Arrêt causé par la commande PTRACE_INTERRUPT,  ou  arrêt-groupe,
              ou  arrêt-ptrace  initial  quand  un  nouvel  enfant est attaché
              (seulement s’il est attaché en utilisant PTRACE_SEIZE).

       PTRACE_EVENT_SECCOMP
              Arrêt différé par une règle seccomp(2) sur l'entrée  appel  sys-
              tème  de  l'observé quand PTRACE_O_TRACESECCOMP a été positionné
              par l'observateur. Les données du message de l'événement seccomp
              (issues  de  la portion SECCOMP_RET_DATA de la règle de filtrage
              seccomp) peuvent être récupérées avec PTRACE_GETEVENTMSG. La sé-
              mantique  de  cet  arrêt  est décrit en détails dans une section
              distincte ci-dessous.

       PTRACE_GETSIGINFO sur les  arrêts  PTRACE_EVENT  renvoie  SIGTRAP  dans
       si_signo, avec si_code configuré à (event<<8) | SIGTRAP.

   Arrêts-appel-système
       Si l'observé était redémarré par PTRACE_SYSCALL ou PTRACE_SYSEMU, l'ob-
       servé entre en arrêt-entrée-appel-système  juste  avant  d'entrer  dans
       n'importe quel appel système (qui ne sera pas exécuté si le redémarrage
       utilisait PTRACE_SYSEMU, quels que soient les changements apportés  aux
       registres à ce point ou à la manière dont l'observé redémarre après cet
       arrêt). Peu importe la méthode qui a conduit en arrêt-entrée-appel-sys-
       tème  si  l’observateur  redémarre l’observé avec PTRACE_SYSCALL, l’ob-
       servé entre en arrêt-sortie-appel-système  quand  l’appel  système  est
       terminé  ou  s'il  est interrompu par un signal (c'est-à-dire qu'un ar-
       rêt-distribution-signal  n'arrive  jamais  entre  un   arrêt-entrée-ap-
       pel-système  et  un  arrêt-sortie-appel-système ; il arrive après l'ar-
       rêt-sortie-appel-système). Si l'observé est poursuivi en utilisant  une
       autre  méthode (notamment PTRACE_SYSEMU), aucun arrêt-sortie-appel-sys-
       tème ne se produit. Remarquez que  toutes  les  mentions  PTRACE_SYSEMU
       s'appliquent également à PTRACE_SYSEMU_SINGLESTEP.

       Toutefois,  même  si l'observé a été poursuivi en utilisant PTRACE_SYS-
       CALL, il n'est pas garanti que le prochain  arrêt  sera  un  arrêt-sor-
       tie-appel-système.  D'autres  possibilités  sont que l'observé pourrait
       s'arrêter dans  un  arrêt  PTRACE_EVENT,  sortir  (s'il  est  entré  en
       _exit(2) ou exit_group(2)), être tué par SIGKILL ou mourir silencieuse-
       ment (s'il s'agit d'un leader de groupe de threads, que l'execve(2) est
       arrivé  dans  un  autre  thread et que ce thread n'est pas suivi par le
       même observateur ; cette situation sera abordée plus tard).

       Les arrêt-entrée-appel-système et arrêt-sortie-appel-système sont  res-
       pectés  par  l'observateur  tant  que waitpid(2) retourne avec WIFSTOP-
       PED(status) vrai, et que WSTOPSIG(status) donne  SIGTRAP.  Si  l'option
       PTRACE_O_TRACESYSGOOD  était configurée par l'observateur, alors WSTOP-
       SIG(status) donnera la valeur (SIGTRAP | 0x80).

       Les arrêts-appel-système peuvent être distingués  d'un  arrêt-distribu-
       tion-signal  avec  SIGTRAP  en demandant PTRACE_GETSIGINFO pour les cas
       suivants.

       si_code <= 0
              SIGTRAP a été distribué comme résultat d'une  action  en  espace
              utilisateur,  par exemple, un appel système (tgkill(2), kill(2),
              sigqueue(3), etc.), l'expiration d'un minuteur POSIX, la modifi-
              cation d'état sur une file de messages POSIX où la fin d'une re-
              quête d'E/S asynchrone.

       si_code == SI_KERNEL (0x80)
              SIGTRAP a été envoyé par le noyau.

       si_code == SIGTRAP ou si_code == (SIGTRAP|0x80)
              C'est un arrêt-appel-système.

       Cependant, les arrêts-appel-système arrivent très  souvent  (deux  fois
       par  appel système) et réaliser PTRACE_GETSIGINFO pour chaque arrêt-ap-
       pel-système pourrait être assez coûteux.

       Certaines architectures permettent de distinguer ces cas  en  examinant
       les registres. Par exemple, sur x86, rax == -ENOSYS en arrêt-entrée-ap-
       pel-système. Puisque SIGTRAP (comme tout autre signal) arrive  toujours
       après  l'arrêt-sortie-appel-système  et que rax ne contient à ce moment
       presque jamais -ENOSYS, le SIGTRAP ressemble à un « arrêt-appel-système
       qui  n'est pas un arrêt-entrée-appel-système » ; autrement dit, il res-
       semble à un « arrêt-sortie-appel-système perdu » et peut  être  détecté
       de  cette  façon.  Une  telle détection est néanmoins fragile, elle est
       donc a éviter.

       L'utilisation  de  l'option  PTRACE_O_TRACESYSGOOD   est   la   méthode
       conseillée  pour  distinguer les arrêts-appel-système des autres sortes
       d'arrêts-ptrace, puisqu'il est fiable et n'induit pas de perte de  per-
       formances.

       Les  arrêt-entrée-appel-système  et  arrêt-sortie-appel-système ne sont
       pas différentiables l'un de  l'autre.  L'observateur  doit  garder  une
       trace de la suite d'arrêts-ptrace afin de ne pas mal interpréter un ar-
       rêt-entrée-appel-système comme un  arrêt-sortie-appel-système  ou  vice
       versa.  Généralement,  l'arrêt-entrée-appel-système  est toujours suivi
       par un arrêt-sortie-appel-système, un arrêt PTRACE_EVENT ou la mort  de
       l'observé ;   aucune   autre   sorte  d'arrêt-ptrace  ne  peut  arriver
       entre-deux. Toutefois, remarquez que les arrêts seccomp  (voir  ci-des-
       sous)  peuvent provoquer des arrêts-sortie-appel-système sans arrêt-en-
       trée-appel-système préalable. Si seccomp, il faut faire attention à  ne
       pas mal interpréter de tels arrêts en arrêts-entrée-appel-système.

       Si  suite  à  un  arrêt-entrée-appel-système, l'observateur utilise une
       commande de  redémarrage  différente  de  PTRACE_SYSCALL,  l'arrêt-sor-
       tie-appel-système n'est pas créé.

       PTRACE_GETSIGINFO  sur  les  arrêts-appel-système  renvoie SIGTRAP dans
       si_signo, avec si_code configuré à SIGTRAP ou (SIGTRAP | 0x80).

   Arrêts PTRACE_EVENT_SECCOMP (Linux 3.5 à Linux 4.7)
       Le comportement des arrêts  PTRACE_EVENT_SECCOMP  et  leur  interaction
       avec  les  autres  types  d'arrêt ptrace a changé entre les versions du
       noyau. Nous documentons ici le comportement lors de  leur  introduction
       dans Linux 4.7 (inclus). Le comportement dans les versions postérieures
       du noyau est documenté dans la section suivante.

       Un arrêt PTRACE_EVENT_SECCOMP se produit à  chaque  fois  qu'une  règle
       SECCOMP_RET_TRACE  est  déclenchée.  Cela est indépendant de la méthode
       utilisée pour  redémarrer  l'appel  système.  En  particulier,  seccomp
       s'exécute  toujours  même  si  l'observé  a  été redémarré en utilisant
       PTRACE_SYSEMU et cet appel système est sauté sans condition.

       Les redémarrages à partir de cet arrêt se comporteront comme si l'arrêt
       s'était  produit  juste  avant l'appel système en question. En particu-
       lier, tant PTRACE_SYSCALL que PTRACE_SYSEMU provoqueront normalement un
       arrêt-entrée-appel-système    ultérieur.   Cependant,   si   après   le
       PTRACE_EVENT_SECCOMP le numéro de l'appel système  est  négatif,  l'ar-
       rêt-entrée-appel-système  et  l'appel lui-même seront tous deux sautés.
       Cela veut dire que si le numéro d'appel système est  négatif  après  un
       PTRACE_EVENT_SECCOMP   et  si  l'observé  est  redémarré  en  utilisant
       PTRACE_SYSCALL, le prochain  arrêt  observé  sera  un  arrêt-sortie-ap-
       pel-système et non un arrêt-entrée-appel-système qui comme on aurait pu
       s'y attendre.

   Arrêts PTRACE_EVENT_SECCOMP (depuis Linux 4.8)
       À partir de Linux 4.8, l'arrêt  PTRACE_EVENT_SECCOMP  a  été  réaménagé
       pour  intervenir  entre  l'arrêt-entrée-appel-système  et  l'arrêt-sor-
       tie-appel-système. Remarquez que seccomp ne s'exécute  plus  (et  aucun
       PTRACE_EVENT_SECCOMP  ne  sera renvoyé) si l'appel système est sauté du
       fait d'un PTRACE_SYSEMU.

       Pratiquement, un arrêt PTRACE_EVENT_SECCOMP  fonctionne  comme  un  ar-
       rêt-entrée-appel-système   (à   savoir   que   les  reprises  utilisant
       PTRACE_SYSCALL provoqueront des arrêts-sortie-appel-système, le  numéro
       de  l'appel  système  peut  être modifié et tous les registres modifiés
       sont visibles également à l'appel système à exécuter). Remarquez  qu'il
       peut  y avoir, sans obligation qu'il y ait déjà eu, un arrêt-entrée-ap-
       pel-système précédent.

       Après un arrêt PTRACE_EVENT_SECCOMP, seccomp sera réexécuté,  avec  une
       règle SECCOMP_RET_TRACE qui fonctionne désormais de la même manière que
       SECCOMP_RET_ALLOW. En particulier, cela veut dire que si les  registres
       ne sont pas modifiés lors d'un arrêt PTRACE_EVENT_SECCOMP, l'appel sys-
       tème aura alors l'autorisation.

   Arrêts PTRACE_SINGLESTEP
       [Les précisions sur ces types d'arrêts sont encore à documenter.]

   Commandes ptrace d'information et de redémarrage
       La  plupart  des   commandes   ptrace   (toutes   sauf   PTRACE_ATTACH,
       PTRACE_SEIZE,  PTRACE_TRACEME,  PTRACE_INTERRUPT et PTRACE_KILL) néces-
       sitent que l'observé soit en arrêt-ptrace, sinon il échoue avec ESRCH.

       Quand l'observé est en arrêt-ptrace, l'observateur peut lire et  écrire
       les  donnés sur l'observé en utilisant les commandes d'information. Ces
       commandes laissent l'observé en état arrêté-ptrace :

           ptrace(PTRACE_PEEKTEXT/PEEKDATA/PEEKUSER, pid, addr, 0);
           ptrace(PTRACE_POKETEXT/POKEDATA/POKEUSER, pid, addr, 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);

       Remarquez que certaines erreurs ne sont pas signalées. Par exemple,  la
       configuration d'informations de signal (siginfo) pourrait être sans ef-
       fet pour certains arrêts-ptrace, alors que l'appel pourrait-être réussi
       (en  renvoyant  0  et  sans définir errno) ; la demande de PTRACE_GETE-
       VENTMSG pourrait réussir et renvoyer une quelconque valeur aléatoire si
       l'arrêt-ptrace  actuel  n'est  pas documenté comme renvoyant un message
       d'événement significatif.

       L'appel

           ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags);

       ne concerne qu'un observé. Les attributs actuels de l'observé sont rem-
       placés.  Les  attributs sont hérités par les nouveaux observés créés et
       « attachés automatiquement »  à  l'aide  d'options  PTRACE_O_TRACEFORK,
       PTRACE_O_TRACEVFORK ou PTRACE_O_TRACECLONE actives.

       Un  autre  groupe de commandes peut redémarrer l'observé arrêté-ptrace.
       Ils sont de la forme :

           ptrace(cmd, pid, 0, sig);

       où  cmd est PTRACE_CONT, PTRACE_LISTEN, PTRACE_DETACH,  PTRACE_SYSCALL,
       PTRACE_SINGLESTEP,  PTRACE_SYSEMU ou PTRACE_SYSEMU_SINGLESTEP. Si l'ob-
       servé est en arrêt-distribution-signal, sig est le  signal  à  injecter
       (s'il  est  non nul). Sinon, sig pourrait être ignoré (lors du redémar-
       rage d'un observé depuis un arrêt-ptrace différent d'un arrêt-distribu-
       tion-signal, il est conseillé de toujours passer 0 à sig).

   Attachement et détachement
       Un thread peut être attaché à l'observateur en utilisant l'appel

           ptrace(PTRACE_ATTACH, pid, 0, 0);

       ou

           ptrace(PTRACE_SEIZE, pid, 0, PTRACE_O_flags);

       PTRACE_ATTACH  envoie  aussi SIGSTOP à ce thread. Si l'observateur veut
       que SIGSTOP soit sans effet, il doit le  supprimer.  Remarquez  que  si
       d'autres signaux sont envoyés en même temps à ce thread pendant l'atta-
       chement, l'observateur pourrait voir l'observé entrer en  arrêt-distri-
       bution-signal  avec d'autres signaux d'abord ! Ces signaux sont d'habi-
       tude réinjectés jusqu'à ce que SIGSTOP soit vu, puis  l'injection  SIG-
       STOP  est  supprimée.  Le bogue de conception ici est qu'un attachement
       ptrace et un SIGSTOP distribués en même temps peuvent entrer en  compé-
       tition et le SIGSTOP risque d'être perdu.

       Puisque  l'attachement  envoie SIGSTOP et que l'observateur le supprime
       normalement, cela risque de forcer le retour d'un EINTR perdu de  l'ap-
       pel  système  en cours d'exécution dans l'observé, tel que c'est décrit
       dans la section Injection et suppression de signal.

       Depuis  Linux 3.4,  PTRACE_SEIZE  peut  être  utilisé  à  la  place  de
       PTRACE_ATTACH.  PTRACE_SEIZE n'arrête pas le processus attaché. Si vous
       devez l'arrêter après attachement (ou à n'importe  quel  autre  moment)
       sans  lui envoyer de signal du tout, utilisez la commande PTRACE_INTER-
       RUPT.

       La requête

           ptrace(PTRACE_TRACEME, 0, 0, 0);

       transforme le thread appelant en observé. L'appel continue d'être  exé-
       cuté  (n'entre  pas en arrêt-ptrace). PTRACE_TRACEME est habituellement
       suivi avec

           raise(SIGSTOP);

       et permet au parent (qui est  maintenant  l'observateur)  de  respecter
       l'arrêt-distribution-signal.

       Si les options PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK ou PTRACE_O_TRA-
       CECLONE font effet, alors les enfants respectivement créés par vfork(2)
       ou  clone(2)  avec  l'attribut CLONE_VFORK, fork(2) ou clone(2) avec le
       signal de sortie configuré à SIGCHLD, et d'autres sortes  de  clone(2),
       sont  automatiquement attachés au même observateur qui à suivi leur pa-
       rent. SIGSTOP est distribué aux enfants, les forçant à  entrer  en  ar-
       rêt-distribution-signal après être sortis de l'appel système qu'ils ont
       créé.

       Le détachement de l'observé est réalisé par :

           ptrace(PTRACE_DETACH, pid, 0, sig);

       PTRACE_DETACH est une opération de redémarrage ;  par  conséquent  elle
       nécessite  que  l'observé soit en arrêt-ptrace. Si l'observé est en ar-
       rêt-distribution-signal, un signal peut être  injecté.  Sinon,  le  pa-
       ramètre sig pourrait être silencieusement ignoré.

       Si l'observé est en cours d'exécution quand l'observateur veut le déta-
       cher, la solution habituelle est d'envoyer SIGSTOP  (en  utilisant  tg-
       kill(2),  pour  s'assurer qu'il va au bon thread), d'attendre que l'ob-
       servé s'arrête en arrêt-distribution-signal pour SIGSTOP et ensuite  de
       le détacher (en supprimant l'injection SIGSTOP). Un bogue de conception
       est que l'observé pourrait entrer dans d'autres arrêts-ptrace et  avoir
       besoin d'être redémarré et attendre encore, jusqu'à ce que SIGSTOP soit
       vu. Encore une autre complication est de s'assurer que l'observé  n'est
       pas déjà arrêté-ptrace, parce qu'aucune distribution de signal n'arrive
       tant qu'il l'est — pas même SIGSTOP.

       Si l'observateur meurt, tous les observés sont automatiquement détachés
       et  redémarrés,  sauf s'il étaient en arrêt-groupe. Le gestion de redé-
       marrage depuis un arrêt-groupe est en ce moment dysfonctionnelle,  mais
       le  comportement « prévu » est de laisser les observés arrêtés et d'at-
       tendre un SIGCONT. Si l'observé est redémarré depuis un arrêt-distribu-
       tion-signal, le signal en attente est injecté.

   execve(2) sous ptrace
       Quand  un  thread de processus multithreadé appelle execve(2), le noyau
       détruit tous les autres threads du processus, et réinitialise l'identi-
       fiant  de thread du thread exécuté à l'identifiant de groupe de threads
       (PID) (ou, pour le présenter autrement, quand un processus multithreadé
       fait  un  execve(2),  à  la  fin  de  l'appel,  il  apparaît  comme  si
       l'execve(2) s'était appliqué au leader de groupe  de  threads,  quelque
       soit le thread qui a fait execve(2)). Cette réinitialisation de l'iden-
       tifiant de thread semble est très déroutante pour les observateurs.

       •  Tous les autres threads s'arrêtent en  arrêt  PTRACE_EVENT_EXIT,  si
          l'option  PTRACE_O_TRACEEXIT  était  activée.  Alors tous les autres
          threads sauf le leader de groupe  de  threads  signalent  leur  mort
          comme  s'il  s'étaient terminés par l'intermédiaire de _exit(2) avec
          un code de retour 0.

       •  L'observé en cours d'exécution modifie  son  identifiant  de  thread
          pendant  qu'il est dans l'execve(2) (rappelez-vous que, sous ptrace,
          le « pid » renvoyé par waitpid(2) ou fourni dans les appels  ptrace,
          est  l'identifiant  de thread de l'observé). Ainsi, l'identifiant de
          thread de l'observé est réinitialisé pour être le même que son iden-
          tifiant  de  processus  (PID),  qui est le même que l'identifiant de
          thread du leader de groupe de threads.

       •  Ensuite un arrêt PTRACE_EVENT_EXEC arrive, si l'option PTRACE_O_TRA-
          CEEXEC était activée.

       •  Si   le   leader   de   groupe   de  threads  a  signalé  son  arrêt
          PTRACE_EVENT_EXIT pendant ce temps, le leader de thread mort à l'air
          de  « revenir  de nulle part » du point de vue de l'observateur (re-
          marque : le leader de groupe de threads ne signale  pas  sa  mort  à
          l'aide  de WIFEXITED(status) tant qu'au moins un autre thread est en
          vie. Cela enlève la possibilité à l'observateur de  le  voir  mourir
          puis  réapparaître).  Si le leader de groupe de threads était encore
          en vie, cela pourrait être vu par l'observateur comme si  le  leader
          de groupe revenait d'un autre appel système que celui dans lequel il
          était entré, ou même « revenait d'un appel  système  même  s'il  n'y
          avait  pas  d'appel  système ».  Si  le  leader de groupe de threads
          n'était pas suivi (ou était suivi par un autre  observateur),  alors
          pendant  execve(2)  il apparaîtra comme s'il était devenu un observé
          de l'observateur de l'observé en cours d'exécution.

       Tous les effets  précédents  sont  des  artifices  de  la  modification
       d'identifiant de thread de l'observé.

       L'option  PTRACE_O_TRACEEXEC  est  l'outil  conseillé pour s'occuper de
       cette situation. D'abord, elle active  l'arrêt  PTRACE_EVENT_EXEC,  qui
       arrive  avant le retour d'execve(2). Dans cet arrêt, l'observateur peut
       utiliser PTRACE_GETEVENTMSG  pour  récupérer  l'ancien  identifiant  de
       thread  de  l'observé  (cette  fonctionnalité a été introduite avec Li-
       nux 3.0). Ensuite, l'option PTRACE_O_TRACEEXEC  désactive  la  création
       obsolète de SIGTRAP dans execve(2).

       Quand  l'observé  reçoit une notification d'arrêt PTRACE_EVENT_EXEC, il
       est garanti qu'à part cet observé et le leader de  groupe  de  threads,
       aucun autre thread du processus n'est en vie.

       Lors  de  la  réception  d'une  notification d'arrêt PTRACE_EVENT_EXEC,
       l'observateur devrait nettoyer toutes ses  structures  de  données  in-
       ternes  décrivant les threads de ce processus et ne garder qu'une seule
       structure de données — celle  qui  décrit  l'unique  observé  en  cours
       d'exécution, avec

           identifiant de thread == identifiant de groupe de threads == identifiant de processus.

       Par  exemple,  soient  deux  threads  qui  appellent  execve(2) en même
       temps :

       *** arrêt-entrée-appel-système obtenu dans le thread 1 : **
       PID1 execve("/bin/truc", "truc" <pas terminé…>
       *** PTRACE_SYSCALL émis pour le thread 1 **
       *** arrêt-entrée-appel-système obtenu dans le thread 2 : **
       PID2 execve("/bin/bidule", "bidule" <pas terminé…>
       *** PTRACE_SYSCALL émis pour le thread 2 **
       *** PTRACE_EVENT_EXEC obtenu pour PID0, PTRACE_SYSCALL émis **
       *** arrêt-sortie-appel-système obtenu pour PID0 : **
       PID0 <… retour d'execve> )             = 0

       Si l'option PTRACE_O_TRACEEXEC n'est pas effective  pour  l'observé  en
       cours   d'exécution  et  si  l'observé  a  été  PTRACE_ATTACHé  et  non
       PTRACE_SEIZEé, le noyau distribue un SIGTRAP supplémentaire à l'observé
       après  le retour d'execve(2). C'est un signal normal (similaire à celui
       qui peut être créé par  kill  -TRAP),  pas  une  sorte  spéciale  d'ar-
       rêt-ptrace.  L'utilisation  de PTRACE_GETSIGINFO pour ce signal renvoie
       si_code configuré à 0 (SI_USER). Ce signal pourrait être bloqué par  un
       masque de signal et pourrait ainsi être distribué (bien) plus tard.

       Normalement, l'observateur (par exemple strace(1)) ne voudrait pas mon-
       trer ce signal SIGTRAP supplémentaire postérieur à execve à  l'utilisa-
       teur, et voudrait supprimer sa distribution à l'observé (si SIGTRAP est
       configuré à SIG_DFL, c'est un signal tueur). Cependant, déterminer quel
       est  le SIGTRAP à supprimer n'est pas simple. La configuration de l'op-
       tion PTRACE_O_TRACEEXEC ou l'utilisation de PTRACE_SEIZE et par  consé-
       quent   la   suppression   du  SIGTRAP  supplémentaire  est  l'approche
       conseillée.

   Vrai parent
       L'interface de programmation de ptrace utilise (parfois mal)  la  norme
       UNIX  de  signalement  de parent ou enfant par l'intermédiaire de wait-
       pid(2). Cela a régulièrement forcé le vrai parent du processus à  arrê-
       ter  de  recevoir plusieurs sortes de notifications de waitpid(2) quand
       le processus enfant est suivi par un autre processus.

       De nombreux bogues de ce type ont été corrigés, mais il en reste encore
       beaucoup dans Linux 2.6.38. Consultez la section BOGUES ci dessous.

       Depuis Linux 2.6.38, ce qui suit est censé fonctionner correctement :

       •  l'exécution  ou la mort par signal sont d'abord signalées à l'obser-
          vateur, puis, quand l'observateur  consomme  le  résultat  de  wait-
          pid(2), au vrai parent (au vrai parent seulement quand l'intégralité
          du processus multithreadé se termine). Si l'observateur et  le  vrai
          parent  sont  le  même processus, le signalement n'est envoyé qu'une
          fois.

VALEUR RENVOYÉE
       En cas de succès, la requête PTRACE_PEEK* renvoie les données demandées
       (mais  consultez  les NOTES), la requête PTRACE_SECCOMP_GET_FILTER ren-
       voie  le  nombre  d'instructions   du   programme   BPF,   la   requête
       PTRACE_GET_SYSCALL_INFO  renvoie  le nombre d'octets disponibles dispo-
       nible pour être écrits par le noyau, alors que les autres requêtes ren-
       voient zéro.

       En  cas  d'erreur, toutes les requêtes renvoient -1 et errno est défini
       pour indiquer l'erreur.  Comme  la  valeur  renvoyée  par  une  requête
       PTRACE_PEEK*  peut  légitimement être -1, l'appelant doit effacer errno
       avant l'appel, et ensuite le vérifier pour savoir si une  erreur  s'est
       produite.

ERREURS
       EBUSY  (i386 seulement) Une erreur est survenue lors de l'allocation ou
              de la libération d'un registre de débogage.

       EFAULT Tentative de lire ou écrire dans une zone mémoire non valable de
              l'observateur  ou  de  l'observé, probablement parce que la zone
              n'était pas projetée ou accessible. Malheureusement sous  Linux,
              certaines  variantes de cette erreur déclencheront EIO ou EFAULT
              plus ou moins arbitrairement.

       EINVAL Tentative d'utiliser une option non valable.

       EIO    La requête request n'est pas valable ou une tentative de lecture
              ou d'écriture dans une zone non valable de mémoire de l'observa-
              teur ou de l'observé a eu lieu. Un problème d'alignement a aussi
              pu  survenir sur une frontière de mot, ou une tentative de redé-
              marrage en envoyant un signal non valable.

       EPERM  Le processus indiqué ne peut pas être suivi. Cela peut être dû à
              un  manque de privilège de l'observateur (la capacité nécessaire
              est CAP_SYS_PTRACE). Les processus non  privilégiés  ne  peuvent
              pas  suivre les processus auxquels ils ne peuvent envoyer de si-
              gnal, ou ceux qui s'exécutent Set-UID/Set-GID, pour des  raisons
              évidentes.  En outre, le processus visé peut être déjà suivi, ou
              (avant Linux 2.6.26) être init(8) (le processus numéro 1).

       ESRCH  Le processus indiqué n'existe pas, ou n'est pas suivi par  l'ap-
              pelant,  ou  n'est  pas arrêté (pour les requêtes qui ont besoin
              d'un observé arrêté).

STANDARDS
       SVr4, 4.3BSD.

NOTES
       Bien que les arguments de ptrace() soient  interprétés  comme  dans  le
       prototype  donné,  la bibliothèque glibc déclare ptrace comme une fonc-
       tion variadique où seul l'argument request est corrigé. Il  vaut  mieux
       toujours  fournir quatre arguments, même si l'opération demandée ne les
       utilise pas, en configurant les arguments non utilisés ou ignorés à  0L
       ou (void *) 0.

       Avant  Linux 2.6.26,  init(8),  le processus numéro 1, ne peut pas être
       suivi.

       Le parent d'observés reste observateur même s'il appelle execve(2).

       La disposition du contenu de la mémoire et de la zone USER dépendent du
       système  d'exploitation et de l'architecture. Le décalage fourni et les
       données renvoyées peuvent ne pas correspondre entièrement avec la défi-
       nition d'une structure struct user.

       La  taille d'un mot (« word ») est déterminée par la version du système
       d'exploitation (par exemple 32 bits pour Linux 32 bits).

       Cette page documente le fonctionnement actuel de ptrace()  sous  Linux.
       Celui-ci  peut varier significativement d'autres types d'UNIX. De toute
       façon, l'utilisation de ptrace() dépend fortement de l'architecture  et
       du système d'exploitation.

   Vérification du mode d'accès ptrace
       Divers  endroits  de l'API de l'espace utilisateur du noyau (pas seule-
       ment les opérations ptrace()) exigent ce qu'on appelle des  « vérifica-
       tions  de mode d'accès ptrace », dont le résultat détermine si une opé-
       ration est autorisée (ou, dans certains cas, fait renvoyer  à  l'opéra-
       tion « read » des données nettoyées). Ces vérifications sont effectuées
       dans les cas où un processus peut accéder à des informations  sensibles
       concernant  un  autre processus ou modifier son état. Les vérifications
       s'opèrent sur la base de facteurs tels que les droits et les  capacités
       des  deux  processus, le fait que le processus « cible » puisse générer
       un fichier core, et des résultats des vérifications effectuées  par  un
       module  de  sécurité  Linux  activé (LSM) (par exemple SELinux, Yama ou
       Smack) et par le LSM commoncap (qui est toujours appelé).

       Avant Linux 2.6.27, toutes les vérifications d'accès étaient d'un  seul
       type. Depuis Linux 2.6.27, on distingue deux niveaux de modes d'accès :

       PTRACE_MODE_READ
              Pour  les  opérations  « read »  ou  d'autres  moins dangereuses
              telles  que :  get_robust_list(2) ;  kcmp(2) ;  la  lecture   de
              /proc/pid/auxv,  /proc/pid/environ  ou de /proc/pid/stat ; ou le
              readlink(2) d'un fichier /proc/pid/ns/*.

       PTRACE_MODE_ATTACH
              Pour les  opérations  « write »  ou  d'autres  plus  dangereuses
              telles  que :  le  rattachement  de  ptrace (PTRACE_ATTACH) à un
              autre    processus    ou    un    appel     process_vm_writev(2)
              (PTRACE_MODE_ATTACH était celui par défaut avant Linux 2.6.27).

       Depuis Linux 4.5, les vérifications de mode d'accès ci-dessus sont com-
       binées (opération OU) avec un ou plusieurs des modificateurs suivants :

       PTRACE_MODE_FSCREDS
              Utiliser l'identifiant de groupe ou d’utilisateur du système  de
              fichiers  de  l'appelant  (voir credentials(7)) ou les capacités
              effectives pour les vérifications LSM.

       PTRACE_MODE_REALCREDS
              Utiliser l'identifiant de groupe ou d’utilisateur réel de  l'ap-
              pelant  ou  les capacités autorisées pour les vérifications LSM.
              C'était l'action par défaut avant Linux 4.5.

       La combinaison d'un des modificateurs de droits avec un des modes d'ac-
       cès  ci-dessus étant classique, certaines macros sont définies dans les
       sources du noyau pour les combinaisons :

       PTRACE_MODE_READ_FSCREDS
              Définie en tant que PTRACE_MODE_READ | PTRACE_MODE_FSCREDS.

       PTRACE_MODE_READ_REALCREDS
              Définie en tant que PTRACE_MODE_READ | PTRACE_MODE_REALCREDS.

       PTRACE_MODE_ATTACH_FSCREDS
              Définie en tant que PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS.

       PTRACE_MODE_ATTACH_REALCREDS
              Définie en tant que PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS.

       Un modificateur supplémentaire peut être lié  (opération  OU)  au  mode
       d'accès :

       PTRACE_MODE_NOAUDIT (depuis Linux 3.3)
              Ne  pas effectuer la vérification de ce mode d'accès. Ce modifi-
              cateur est utilisé pour les vérifications de mode d'accès ptrace
              (telles  que celles faites lors de la lecture de /proc/pid/stat)
              qui filtrent ou nettoient la sortie au lieu de renvoyer une  er-
              reur  à  l'appelant.  Dans ces cas, l'accès au fichier n'est pas
              une violation de sécurité et il n'y aucune raison de générer  un
              enregistrement  de  l'évaluation de la sécurité. Ce modificateur
              supprime la génération d'un tel enregistrement pour cette  véri-
              fication d'accès particulière.

       Remarquez  que  toutes les constantes PTRACE_MODE_* décrites dans cette
       sous-section sont internes au noyau et invisibles à  l'espace  utilisa-
       teur.  Le nom des constantes est mentionné ici pour identifier les dif-
       férents types de vérification des modes d'accès ptrace effectuées  pour
       divers  appels système et divers accès à des pseudofichiers (comme dans
       /proc). Ces noms sont utilisés dans d'autres pages de manuel pour four-
       nir un raccourci simple d'identification des vérifications du noyau.

       L'algorithme  utilisé pour la vérification des modes d'accès ptrace dé-
       termine si le processus appelant est autorisé à effectuer l'action cor-
       respondante  sur  le  processus  cible  (pour  l'ouverture des fichiers
       /proc/pid, le « processus appelant » est celui qui ouvre le fichier  et
       le  processus dont le PID correspond est le « processus cible »). L’al-
       gorithme est comme suit :

       (1)  Si le thread appelant  et  cible  sont  dans  le  même  groupe  de
            threads, l'accès est toujours autorisé.

       (2)  Si le mode d'accès indique PTRACE_MODE_FSCREDS, lors de la vérifi-
            cation de la prochaine étape, utiliser l'identifiant d'utilisateur
            et  de  groupe du système de fichiers appelant (comme indiqué dans
            credentials(7), les identifiants d'utilisateur  et  de  groupe  du
            système  de  fichiers  ont presque toujours la même valeur que les
            identifiants effectifs correspondant).

            Sinon le mode d'accès indique PTRACE_MODE_REALCREDS, donc utiliser
            l'identifiant  d'utilisateur et de groupe réels de l'appelant lors
            des vérifications de la prochaine étape (la plupart  des  API  qui
            vérifient  les  identifiants  d’utilisateur et de groupe utilisent
            les identifiants effectifs. Pour des raisons historiques, la véri-
            fication PTRACE_MODE_REALCREDS utilise plutôt ceux réels).

       (3)  Interdire l'accès si rien de ce qui suit n'est vrai :

            •  Les  identifiants  utilisateur  réel,  effectif et défini de la
               cible correspondent à l'identifiant utilisateur  de  l'appelant
               et les identifiants réels, effectifs et définis de groupe de la
               cible correspondent à ceux de groupe de l'appelant.

            •  L'appelant a la capacité CAP_SYS_PTRACE dans l'espace  de  noms
               utilisateur de la cible.

       (4)  Interdire  l'accès si l'attribut « dumpable » du processus cible a
            une autre  valeur  que  1  (SUID_DUMP_USER ;  voir  le  point  sur
            PR_SET_DUMPABLE  dans  prctl(2)) et l'appelant n'a pas la capacité
            CAP_SYS_PTRACE dans l'espace de noms de l'utilisateur du processus
            cible.

       (5)  L'interface security_ptrace_access_check() du LSM du noyau est ap-
            pelée pour voir si l'accès ptrace est autorisé. Le résultat dépend
            des LSM. L'implémentation de cette interface dans le LSM commoncap
            suit les étapes suivantes :

            (5.1)  Si le mode d'accès comprend  PTRACE_MODE_FSCREDS,  utiliser
                   l’ensemble  des  capacités effectives de l'appelant dans la
                   prochaine vérification ; sinon (si le mode d'accès  indique
                   PTRACE_MODE_REALCREDS),  utiliser  l’ensemble des capacités
                   autorisées de l'appelant.

            (5.2)  Interdire l'accès si rien de ce qui suit n'est vrai :

                   •  Les processus appelant et cible sont dans le même espace
                      de  noms utilisateur et les capacités de l'appelant sont
                      un surensemble des  capacités  autorisées  du  processus
                      cible.

                   •  L'appelant a la capacité CAP_SYS_PTRACE dans l'espace de
                      noms utilisateur du processus cible.

                   Remarquez que le LSM commoncap ne fait  pas  de  différence
                   entre PTRACE_MODE_READ et PTRACE_MODE_ATTACH.

       (6)  Si  l'accès  n'a pas été interdit par une étape précédente, il est
            autorisé.

   /proc/sys/kernel/yama/ptrace_scope
       Sur des systèmes ayant un Yama Linux  Security  Module  (LSM)  installé
       (donc  si  le  noyau a été configuré avec CONFIG_SECURITY_YAMA), le fi-
       chier /proc/sys/kernel/yama/ptrace_scope (disponible depuis  Linux 3.4)
       peut être utilisé pour restreindre la possibilité d'observer un proces-
       sus avec ptrace() (et ainsi,  celle  d'utiliser  des  outils  tels  que
       strace(1)  et gdb(1)). Le but de telles restrictions est d'empêcher des
       attaques en cascade par lesquelles un processus infecté peut s'attacher
       avec  un  ptrace  à d'autres processus sensibles (comme un agent GPG ou
       une session SSH) appartenant à l'utilisateur, afin  d'obtenir  d'autres
       droits  qui  pourraient exister en mémoire et ainsi, élargir l'objectif
       de l'attaque.

       Plus précisément, le Yama LSM limite deux types d'opérations :

       •  Toute opération qui effectue une vérification PTRACE_MODE_ATTACH  de
          mode  d'accès (par exemple, PTRACE_ATTACH de ptrace(), voir le point
          sur les « vérifications de mode d'accès ptrace » ci-dessus).

       •  PTRACE_TRACEME ptrace().

       Un processus ayant la capacité CAP_SYS_PTRACE peut mettre à jour le fi-
       chier  /proc/sys/kernel/yama/ptrace_scope avec une ou plusieurs des va-
       leurs suivantes :

       0 (droits ptrace « classiques »)
              Aucune restriction supplémentaire sur les opérations qui  effec-
              tuent  des  vérifications  PTRACE_MODE_ATTACH (au-delà de celles
              imposées par le LSM commoncap et les autres).

              L'utilisation de PTRACE_TRACEME ne change pas.

       1 (« ptrace restreint » (valeur par défaut)
              Lors d'une opération qui exige une vérification  PTRACE_MODE_AT-
              TACH,   le  processus  appelant  doit  avoir  soit  la  capacité
              CAP_SYS_PTRACE dans l'espace de noms  utilisateur  du  processus
              cible, soit une relation prédéfinie avec le processus cible. Par
              défaut, la relation prédéfinie est que le processus  cible  doit
              être un descendant de l'appelant.

              Un  processus  cible peut utiliser l'opération PR_SET_PTRACER de
              prctl(2) pour déclarer un PID supplémentaire autorisé  à  effec-
              tuer des opérations PTRACE_MODE_ATTACH sur la cible. Voir le fi-
              chier  Documentation/admin-guide/LSM/Yama.rst  des  sources   du
              noyau (ou Documentation/security/Yama.txt avant Linux 4.13) pour
              plus de détails.

              L'utilisation de PTRACE_TRACEME ne change pas.

       2 (attachement « admin-only »)
              Seuls les processus ayant la capacité CAP_SYS_PTRACE dans  l'es-
              pace  de noms de l'utilisateur du processus cible peuvent effec-
              tuer des opérations PTRACE_MODE_ATTACH ou observer  les  enfants
              qui utilisent PTRACE_TRACEME.

       3 (« pas d'attachement »)
              Aucun processus ne peut effectuer d'opération PTRACE_MODE_ATTACH
              ou observer les enfants qui utilisent PTRACE_TRACEME.

              Une fois que cette valeur a été écrite dans le fichier, elle  ne
              peut pas être modifiée.

       Par  rapport  aux valeurs 1 et 2, remarquez que la création d'un nouvel
       espace de noms utilisateur supprime de fait la protection apportée  par
       Yama. Cela parce qu'un processus dans l'espace de noms de l'utilisateur
       parent dont l'identifiant utilisateur effectif correspond  à  celui  de
       l'espace   de   noms   enfant   a   toutes  les  capacités  (y  compris
       CAP_SYS_PTRACE) lorsqu'il effectue des opérations dans l'espace de noms
       utilisateur  de l'enfant (et les descendants supprimés plus tard de cet
       espace de noms). Par conséquent, quand un processus  essaie  d'utiliser
       les  espaces de noms utilisateur pour s'isoler lui-même, il affaiblit à
       son insu les protections apportées par le Yama LSM.

   différences entre bibliothèque C et noyau
       L'interface de programmation de l'appel système est différente pour les
       requêtes  PTRACE_PEEKTEXT,  PTRACE_PEEKDATA  et PTRACE_PEEKUSER : elles
       stockent le résultat à l’adresse indiquée par le paramètre data, et  la
       valeur de retour est l’attribut d’erreur. La fonction glibc encapsulant
       cet appel fournit une interface détaillée dans la  section  DESCRIPTION
       ci-dessus,  et  le  résultat qu'elle renvoie est le résultat de l'appel
       système.

BOGUES
       Sur les machines ayant des en-têtes du noyau  Linux 2.6,  PTRACE_SETOP-
       TIONS  est déclaré avec une valeur différente de celle de Linux 2.4. De
       ce fait, les applications compilées  avec  des  en-têtes  du  noyau Li-
       nux 2.6  ne  peuvent  pas s'exécuter sous Linux 2.4. Il est possible de
       contourner  cette  difficulté  en  redéfinissant  PTRACE_SETOPTIONS   à
       PTRACE_OLDSETOPTIONS, si cette dernière constante est définie.

       Les  notifications  d'arrêt-groupe  sont envoyées à l'observateur, mais
       pas au vrai parent. C'était encore vrai sur 2.6.38.6.

       Si un leader de groupe de threads  est  suivi  et  existe  en  appelant
       _exit(2), un arrêt PTRACE_EVENT_EXIT lui arrivera (si réclamé), mais la
       notification WIFEXITED suivante ne sera pas distribuée avant la fin  de
       tous  les autres threads. Comme expliqué précédemment, si un des autres
       threads appelle execve(2), la mort du leader de groupe  de  threads  ne
       sera  jamais signalée. Si le thread exécuté n'est pas suivi par cet ob-
       servateur, l'observé  ne  saura  jamais  qu'execve(2)  est  arrivé.  Un
       contournement  possible  est  de PTRACE_DETACHer le leader de groupe de
       threads au lieu de le redémarrer dans ce cas. C'était encore  vrai  sur
       2.6.38.6.

       Un  signal SIGKILL pourrait encore provoquer un arrêt PTRACE_EVENT_EXIT
       avant une véritable mort du signal. Cela pourrait évoluer  à  l'avenir.
       SIGKILL  est  supposé  tuer  immédiatement les tâches même sous ptrace.
       C'était encore vrai sur Linux 3.13.

       Certains appels système renvoient EINTR si un signal  a  été  envoyé  à
       l'observé,  mais  que la distribution a été supprimée par l'observateur
       (c'est une opération tout à fait caractéristique : elle est normalement
       réalisée  par  les débogueurs sur tous les attachements, afin de ne pas
       introduire de SIGSTOP défectueux). Depuis Linux 3.2.9, les appels  sys-
       tème  suivants sont concernés (cette liste est sans doute incomplète) :
       epoll_wait(2) et read(2) depuis un descripteur de  fichier  inotify(7).
       Le  symptôme  classique  de ce bogue est qu'en attachant à un processus
       quiescent avec la commande

           strace -p <process-ID>

       alors, au lieu de la ligne de sortie habituelle attendue comme

           restart_syscall(<... reprise de l'appel interrompu ...>_

       ou

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

       (« _ » indique la position du curseur),  plusieurs  lignes  sont  affi-
       chées. Par exemple :

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

       Ce  qui  n'est  pas  visible ici est que le processus a été bloqué dans
       epoll_wait(2) avant que strace(1) ne s'y soit attaché. L'attachement  a
       forcé  epoll_wait(2)  à revenir dans l'espace utilisateur avec l'erreur
       EINTR. Dans ce cas particulier, le programme a réagit à EINTR en  véri-
       fiant  l'heure  actuelle et en exécutant encore epoll_wait(2) (les pro-
       grammes qui ne s'attendent pas à de  telles  erreurs  EINTR  « perdue »
       risquent   de   se  comporter  de  façon  inattendue  sur  une  attache
       strace(1)).

       Contrairement  aux  règles  normales,  l'enveloppe  de  la  glibc  pour
       ptrace() peut positionner errno sur zéro.

VOIR AUSSI
       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)

TRADUCTION
       La  traduction française de cette page de manuel a été créée par Chris-
       tophe Blaess <https://www.blaess.fr/christophe/>, Stéphan  Rafin  <ste-
       phan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, Fran-
       çois Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe  Gué-
       rard  <fevrier@tigreraye.org>,  Jean-Luc  Coulon (f5ibh) <jean-luc.cou-
       lon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>,  Thomas  Huriaux
       <thomas.huriaux@gmail.com>,  Nicolas François <nicolas.francois@centra-
       liens.net>, Florentin Duneau <fduneau@gmail.com>, Simon  Paillard  <si-
       mon.paillard@resel.enst-bretagne.fr>,    Denis   Barbier   <barbier@de-
       bian.org>, David Prévot <david@tilapin.org>  et  Jean-Philippe  MENGUAL
       <jpmengual@debian.org>

       Cette traduction est une documentation libre ; veuillez vous reporter à
       la       GNU       General       Public        License        version 3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩  concernant  les conditions
       de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de  manuel,
       veuillez envoyer un message à ⟨debian-l10n-french@lists.debian.org⟩.

Pages du manuel de Linux 6.03   5 février 2023                       ptrace(2)

Generated by dwww version 1.15 on Sat Jun 29 01:42:09 CEST 2024.