Provided by: manpages-fr-dev_4.15.0-9_all bug

NOM

       ptrace - Suivre un processus

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émentation de points d'arrêt pour le débogage, et pour suivre les appels système.

       Un observé doit d'abord être attaché  à  l'observateur.  L'attachement  et  les  commandes
       suivantes  sont  par  thread :  dans  un  processus  multithreadé, chaque thread peut être
       attaché individuellement à un  observateur  (é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 waitpid(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'observé.  L'observateur  peut  également  laisser
       continuer l'exécution de l'observé, en ignorant éventuellement le signal  ayant  déclenché
       l'arrê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é à continuer normalement, en
       mode non suivi, avec PTRACE_DETACH.

       La valeur de l'argument request indique précisément l'action à entreprendre.

       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_INTERRUPT 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 section 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 processus (voir <sys/user.h>). Le mot est
              renvoyée en résultat de ptrace(). En principe, l'adresse doit être alignée sur  une
              frontière  de  mots,  bien  que  cela  varie  selon les architectures. Consultez la
              section NOTES. (data est ignoré, consultez la section NOTES).

       PTRACE_POKETEXT, PTRACE_POKEDATA
              Copier le mot data vers l'adresse addr de  la  mémoire  de  l'observé.  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
              interdites.

       PTRACE_GETREGS, PTRACE_GETFPREGS
              Copier les registres généraux ou du processeur en virgule flottante  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épendante  de
              l'architecture, le type de registres à lire. NT_PRSTATUS (avec une valeur numérique
              de  1)  a  pour  conséquence  habituelle  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 inversé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'arrê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 siginfo_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érencier 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  à  partir de laquelle la copie des signaux devrait commencer et le nombre
              de signaux à copier. Les structures siginfo_t sont copié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 sigprocmask(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 sizeof(sigset_t)).

       PTRACE_SETSIGMASK (depuis Linux 3.11)
              Modifier  le  masque  des  signaux  bloqués  (consultez sigprocmask(2)) à la valeur
              indiquée 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 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 automatiquement à 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é appelle 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éinitialisé à 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  processus,  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 terminaison. 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 automatiquement à 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 automatiquement à 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  waitpid(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'observateur 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  données  du  message  de l'événement
                     seccomp (issues de la partie 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 seccomp. 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é, laisser 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 capacité CAP_SYS_ADMIN, n'ait
                     pas de protection seccomp installée et n'ait pas de PTRACE_O_SUSPEND_SECCOMP
                     positionné sur lui-même.

       PTRACE_GETEVENTMSG (depuis Linux 2.5.46)
              Récupérer  un  message  (dans  un  unsigned long) concernant l'événement 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 interpré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 paramètre data. Le paramètre  addr  est
              ignoré.  Cette  requête  n'est  actuellement prise en charge que sur arm (et arm64,
              quoique uniquement à 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 programmes comme
              User Mode Linux, qui veulent émuler  tous  les  appels  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 processus 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 observé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,  envoyez  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  effectif,  l’appel  système  est
              interrompu  et l'arrêt-sortie-appel-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é envoyé, l’observé s’arrête avec
              PTRACE_EVENT_STOP et WSTOPSIG(status) renvoie le signal d’arrêt. Si n’importe  quel
              autre  arrê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_INTERRUPT  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érification
              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  commandes PTRACE_INTERRUPT et PTRACE_LISTEN. Le
              comportement « seized » qui vient  d'être  décrit  est  récupéré  par  les  enfants
              automatiquement  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 à activer immédiatement.

              Le   droit   d'effectuer   un   PTRACE_SEIZE   est   géré   par   une  vérification
              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 assez grand pour
              stocker le programme BPF, soit NULL si le programme 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
              EMEDIUMTYPE.

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

       PTRACE_DETACH
              Relancer l'observé arrêté comme avec  PTRACE_CONT,  mais  en  commençant  par  s'en
              détacher.  Sous  Linux  un  observé peut être détaché 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'index 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 lequel 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 indiquée par le paramètre addr, les  données  de  sortie  sont
              tronquées.

              La structure ptrace_syscall_info contient les champs suivants :

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

              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 indiqué par le champ op.

              Le champ op prend une  des  valeurs  suivantes  (définies  dans  <linux/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'action  par  défaut  est  de tuer le
       processus), tous les threads se terminent. 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-distribution-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 multithreadé (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  processus (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. Malheureusement, 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é arrê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 garanti que waitpid(WNOHANG) signale de
       façon fiable  l'état  de  mort  de  l'observé  si  une  opération  ptrace  renvoie  ESRCH.
       waitpid(WNOHANG)  pourrait  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'arrê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’auront aucun effet sur lui et  il
       distribuera   des  notifications  waitpid(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'observé  est  prêt  à
       accepter   des   commandes   ptrace   de  l'observateur  sont  appelés  arrêt-ptrace.  Les
       arrêts-ptrace   peuvent   ensuite   être   sous-divisés   en    arrêt-distribution-signal,
       arrêt-groupe, arrêt-appel-systè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 système « wait »). La plupart de cette page
       de manuel suppose que l'observateur 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'utiliser 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-signal,  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 observé, 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 injection 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 signal 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 renvoyé par WSTOPSIG(status). Si le signal
       est SIGTRAP, cela pourrait être un  arrêt-ptrace  de  nature  différente ;  consultez  les
       sections  Arrê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'observateur 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
       utilise  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 suppression du signal ; cependant,
       des bogues du noyau existent et certains appels système échouent avec EINTR même si  aucun
       signal observable n'est injecté dans l'observé.

       Lors   du   redémarrage   des   commandes   ptrace   émises  dans  d'autres  arrê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 remarque 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 arrê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'observé, 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-distribution-signal pour le ou les signaux différents de SIGCONT,
       s'ils étaient en attente quand SIGCONT a été distribué. Autrement dit, SIGCONT pourrait 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 pouvait pas être injecté.

       PTRACE_GETSIGINFO  peut être utilisé pour récupérer une structure siginfo_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 commande 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'arrê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, seulement après avoir été injecté par l'observateur (ou après avoir été
       envoyé à 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)   retourne   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, SIGTTIN 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_GETSIGINFO é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 SIGKILL) à 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'observateur  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 prochain
       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 redé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é  entrera  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'observé 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_GETEVENTMSG 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_GETEVENTMSG 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 actif ;
              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 systè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'observé  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-système  si
       l’observateur    redémarre    l’observé    avec   PTRACE_SYSCALL,   l’observé   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   arrêt-distribution-signal   n'arrive   jamais   entre  un
       arrêt-entrée-appel-système   et   un   arrêt-sortie-appel-système ;   il   arrive    après
       l'arrêt-sortie-appel-système).  Si  l'observé est poursuivi en utilisant une autre méthode
       (notamment PTRACE_SYSEMU), aucun arrêt-sortie-appel-systè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_SYSCALL, il n'est pas
       garanti que le prochain arrêt sera un  arrêt-sortie-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 silencieusement (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   respectés  par
       l'observateur  tant  que  waitpid(2)  retourne  avec  WIFSTOPPED(status)  vrai,   et   que
       WSTOPSIG(status)  donne  SIGTRAP.  Si  l'option PTRACE_O_TRACESYSGOOD était configurée par
       l'observateur, alors WSTOPSIG(status) donnera la valeur (SIGTRAP | 0x80).

       Les arrêts-appel-système  peuvent  être  distingués  d'un  arrêt-distribution-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 modification d'état sur une file de messages POSIX où la
              fin d'une requê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-appel-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-appel-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
       ressemble à 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 performances.

       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 arrê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-dessous)   peuvent  provoquer  des  arrêts-sortie-appel-système  sans
       arrêt-entré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-sortie-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 à 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  particulier,  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'arrê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-appel-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-sortie-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 arrê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-appel-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 systè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écessitent 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 effet 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_GETEVENTMSG  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 remplacé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'observé est en arrêt-distribution-signal,
       sig est le signal à injecter (s'il est non nul). Sinon, sig pourrait être ignoré (lors  du
       redémarrage  d'un observé depuis un arrêt-ptrace différent d'un arrêt-distribution-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'attachement, l'observateur pourrait voir l'observé  entrer  en
       arrêt-distribution-signal  avec  d'autres  signaux  d'abord !  Ces signaux sont d'habitude
       réinjectés jusqu'à ce que SIGSTOP soit vu, puis  l'injection  SIGSTOP  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'appel 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_INTERRUPT.

       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_TRACECLONE 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
       parent.    SIGSTOP    est    distribué    aux   enfants,   les   forçant   à   entrer   en
       arrê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 arrêt-distribution-signal, un signal
       peut être injecté. Sinon, le paramètre sig pourrait être silencieusement ignoré.

       Si l'observé est en cours d'exécution quand l'observateur veut le  détacher,  la  solution
       habituelle  est  d'envoyer SIGSTOP (en utilisant tgkill(2), pour s'assurer qu'il va au bon
       thread), d'attendre que l'observé 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'attendre   un   SIGCONT.   Si   l'observé   est   redémarré   depuis   un
       arrêt-distribution-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'identifiant 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'identifiant  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
          identifiant 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_TRACEEXEC  é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 (remarque : 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 Linux 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 internes 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'arrê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 montrer ce signal
       SIGTRAP supplémentaire postérieur à execve  à  l'utilisateur,  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'option  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 waitpid(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'observateur,  puis,  quand
          l'observateur  consomme  le  résultat  de  waitpid(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

       On  success,  the  PTRACE_PEEK*  requests  return  the requested data (but see NOTES), the
       PTRACE_SECCOMP_GET_FILTER request returns the number of instructions in the  BPF  program,
       the PTRACE_GET_SYSCALL_INFO request returns the number of bytes available to be written by
       the kernel, and other requests return zero.

       On error, all requests return -1, and errno is set to indicate the error. Since the  value
       returned  by  a  successful  PTRACE_PEEK*  request  may be -1, the caller must clear errno
       before the call, and then check  it  afterward  to  determine  whether  or  not  an  error
       occurred.

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'observateur 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  signal,  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  (sur  les
              noyaux antérieurs à 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'appelant, ou n'est pas
              arrêté (pour les requêtes qui ont besoin d'un observé arrêté).

CONFORMITÉ

       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 fonction 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.

       Dans les noyaux Linux antérieurs à 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éfinition 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  seulement  les  opérations
       ptrace())  exigent  ce qu'on appelle des « vérifications 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ération  « 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 combiné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'appelant  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'accè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  modificateur  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  erreur  à 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érification 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  utilisateur.  Le  nom des constantes est
       mentionné ici pour identifier les diffé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  fournir  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 correspondante 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’algorithme 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érification 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érification
          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  appelé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 :

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

          b) 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  fichier  /proc/sys/kernel/yama/ptrace_scope
       (disponible depuis Linux 3.4) peut être utilisé pour restreindre la possibilité d'observer
       un processus 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  fichier
       /proc/sys/kernel/yama/ptrace_scope avec une ou plusieurs des valeurs suivantes :

       0 (droits ptrace « classiques »)
              Aucune  restriction  supplémentaire  sur  les   opérations   qui   effectuent   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_ATTACH,  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é   à   effectuer   des   opérations
              PTRACE_MODE_ATTACH      sur       la       cible.       Voir       le       fichier
              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'espace  de  noms  de
              l'utilisateur    du    processus    cible    peuvent   effectuer   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 2.6, PTRACE_SETOPTIONS est déclaré avec une
       valeur différente de celle du noyau 2.4. De ce fait, les applications compilées  avec  des
       en-têtes  du  noyau 2.6  ne peuvent pas s'exécuter sous des noyaux 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  observateur,  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  systè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 affiché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érifiant l'heure actuelle et en exécutant encore epoll_wait(2)  (les  programmes
       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)

COLOPHON

       Cette  page  fait partie de la publication 5.13 du projet man-pages Linux. Une description
       du projet et des instructions pour signaler des anomalies et la dernière version de  cette
       page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION

       La  traduction  française  de  cette  page  de  manuel  a  été créée par Christophe Blaess
       <https://www.blaess.fr/christophe/>, Stéphan  Rafin  <stephan.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.coulon@wanadoo.fr>,    Julien    Cristau    <jcristau@debian.org>,    Thomas   Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin
       Duneau  <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis
       Barbier <barbier@debian.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⟩.