plucky (2) ptrace.2.gz

Provided by: manpages-fr-dev_4.25.1-1_all bug

NOM

       ptrace - Suivre un processus

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

       #include <sys/ptrace.h>

       long ptrace(enum __ptrace_request op, 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  opérations  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 op indique précisément l'opération à entreprendre.

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

              L'opération PTRACE_TRACEME ne sert qu'à  l'observé.  Les  opérations  restantes  ne  servent  qu'à
              l'observateur.  Dans  les observations suivantes, pid précise l'identifiant de thread de l'observé
              sur lequel agir. Pour d'autres opérations 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
              opérations 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 opérations 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_SETRGS
       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 opération
              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 opérations 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 d'appel système d'arrêt */
                      __u32 arch;     /* Valeur AUDIT_ARCH_* ; voir seccomp(2) */
                      __u64 instruction_pointer; /* Pointeur vers l'instruction du processeur */
                      __u64 stack_pointer;    /* Pointeur vers la pile du processeur */
                      union {
                          struct {    /* op == PTRACE_SYSCALL_INFO_ENTRY */
                              __u64 nr;       /* Numéro de l'appel système */
                              __u64 args[6];  /* Paramètres de l'appel système */
                          } entry;
                          struct {    /* op == PTRACE_SYSCALL_INFO_EXIT */
                              __s64 rval;     /* Code de retour de l'appel système */
                              __u8 is_error;  /* Attribut d'erreur de l'appel système ;
                                                 Booléen : rval contient-il
                                                 un code d'erreur (-ERRCODE) ou
                                                 un code de retour de non erreur ? */
                          } exit;
                          struct {    /* op == PTRACE_SYSCALL_INFO_SECCOMP */
                              __u64 nr;       /* Numéro de l'appel système */
                              __u64 args[6];  /* Paramètres de l'appel système */
                              __u32 ret_data; /* Partie SECCOMP_RET_DATA de la valeur
                                                 de retour de SECCOMP_RET_TRACE */
                          } seccomp;
                      };
                  };

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

              Dans le cas où une entrée ou une sortie d'appel système s'interrompt, les  données  renvoyées  par
              PTRACE_GET_SYSCALL_INFO  sont  limitées  au  type  PTRACE_SYSCALL_INFO_NONE  à  moins que l'option
              PTRACE_O_TRACESYSGOOD ne soit définie avant  que  l'arrêt  de  l'appel  système  correspondant  se
              produise.

   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 opérations 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èmearrê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 l'opération 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 opérations 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 opérations 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 opération 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 à Linux 4.7)
       Le  comportement des arrêts PTRACE_EVENT_SECCOMP et leur interaction avec les autres types d'arrêt ptrace
       a changé entre les versions du noyau. Nous documentons ici le comportement lors de leur introduction dans
       Linux 4.7 (inclus). Le comportement dans les versions postérieures du noyau est documenté dans la section
       suivante.

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

       Les  redémarrages  à  partir  de  cet  arrêt se comporteront comme si l'arrêt s'était produit juste avant
       l'appel  système  en  question.  En  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.

       L'opération

           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

       En cas de succès, l'opération PTRACE_PEEK* renvoie les données  demandées  (mais  consultez  les  NOTES),
       l'opération  PTRACE_SECCOMP_GET_FILTER  renvoie  le  nombre  d'instructions du programme BPF, l'opération
       PTRACE_GET_SYSCALL_INFO renvoie le nombre d'octets disponibles disponible pour être écrits par le  noyau,
       alors que les autres opérations renvoient zéro.

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

ERREURS

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

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

       EINVAL Tentative d'utiliser une option non valable.

       EIO    L'opération op 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 un signal non valable a été spécifié pendant  une  opération
              de redémarrage.

       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 (avant Linux 2.6.26) être init(8) (le processus numéro 1).

       ESRCH  Le  processus  indiqué  n'existe pas, ou n'est pas suivi par l'appelant, ou n'est pas arrêté (pour
              les opérations qui ont besoin d'un observé arrêté).

STANDARDS

       Aucun.

HISTORIQUE

       SVr4, 4.3BSD.

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

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

       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 :

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

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

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

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

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

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

   /proc/sys/kernel/yama/ptrace_scope
       Sur des systèmes ayant un Yama Linux Security Module (LSM) installé (donc si le  noyau  a  été  configuré
       avec  CONFIG_SECURITY_YAMA),  le 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  opérations  PTRACE_PEEKTEXT,
       PTRACE_PEEKDATA  et  PTRACE_PEEKUSER :  elles  stockent le résultat à l’adresse indiquée par le paramètre
       data, et la valeur de retour est l’attribut d’erreur. La fonction glibc encapsulant cet appel fournit une
       interface détaillée dans la section DESCRIPTION ci-dessus, et le résultat qu'elle renvoie est le résultat
       de l'appel système.

BOGUES

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

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

       Si un leader de groupe de threads est suivi et existe en appelant _exit(2),  un  arrêt  PTRACE_EVENT_EXIT
       lui arrivera (si réclamé), mais la notification WIFEXITED suivante ne sera pas distribuée avant la fin de
       tous les autres threads. Comme expliqué précédemment, si un des autres threads appelle execve(2), la mort
       du  leader  de  groupe  de  threads ne sera jamais signalée. Si le thread exécuté n'est pas suivi par cet
       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)

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