Loading

NOM

       ptrace - Suivre un processus

SYNOPSIS

       #include <sys/ptrace.h>

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

       L’appel  système  ptrace()  fournit  au  processus  parent  un moyen de
       contrôler l’exécution  d’un  autre  processus  et  d’éditer  son  image
       mémoire.    L’utilisation    primordiale    de   cette   fonction   est
       l’implémentation de points d’arrêt pour le débogage, et pour suivre les
       appels système.

       Le  père peut démarrer un suivi en appelant fork(2) et que le fils créé
       fasse un PTRACE_TRACEME, suivi (en général) par un exec(3).  Autrement,
       le  père peut commencer un suivi sur un processus existant en utilisant
       PTRACE_ATTACH.

       Le processus fils suivi s’arrêtera à chaque fois qu’un signal lui  sera
       délivré,  même  si le signal est ignoré (à l’exception de SIGKILL qui a
       les effets habituels). Le père sera prévenu à son prochain  wait(2)  et
       pourra  inspecter  et  modifier le processus fils pendant son arrêt. Le
       parent  peut  également  faire  continuer  l’exécution  de  son   fils,
       éventuellement  en  ignorant  le  signal  ayant  déclenché  l’arrêt, ou
       envoyant un autre signal.

       Quand le  père  a  fini  le  suivi,  il  peut  terminer  le  fils  avec
       PTRACE_KILL   ou  le  faire  continuer  normalement,  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 père. Tout signal
              (sauf SIGKILL) reçu par le processus l’arrêtera, et le père sera
              notifié  grâce  à  wait(2).  De  plus,  les  appels ultérieurs à
              execve(2) par ce processus lui enverront SIGTRAP, ce  qui  donne
              au  père  la  possibilité  de reprendre le contrôle avant que le
              nouveau programme continue son exécution. Un processus  ne  doit
              pas  envoyer  cette  requête  si  son  père  n’est pas prêt à le
              suivre. Dans cette requête pid, addr, et data sont ignorés.

       La requête ci-dessus ne sert que dans le processus fils. Les autres  ne
       servent  que dans le père. Par la suite, pid précise le fils sur lequel
       agir. Pour les requêtes autres  que  PTRACE_KILL,  le  fils  doit  être
       arrêté.

       PTRACE_PEEKTEXT, PTRACE_PEEKDATA
              Lire  un  mot  à l’adresse addr dans l’espace mémoire du fils et
              renvoyer la valeur en résultat de ptrace(). Linux ne sépare  pas
              les  espaces  d’adressage  de code et de données, ainsi ces deux
              requêtes sont équivalentes. L’argument data est ignoré.

       PTRACE_PEEKUSER
              Lire un mot à l’adresse addr dans l’espace  USER  du  fils,  qui
              contient les registres et diverses informations sur le processus
              (voir <sys/user.h>). La  valeur  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é.

       PTRACE_POKETEXT, PTRACE_POKEDATA
              Copier  un  mot depuis l’adresse data de la mémoire du père vers
              l’adresse addr de la mémoire du fils.  Comme  précédemment,  les
              deux requêtes sont équivalentes.

       PTRACE_POKEUSER
              Copier  un  mot  depuis l’emplacement data de la mémoire du père
              vers l’emplacement addr dans l’espace USER  du  processus  fils.
              Comme  plus  haut, 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, vers l’adresse data du père. Voir  <sys/user.h>  pour
              les détails sur le format des données (addr est ignoré).

       PTRACE_GETSIGINFO (depuis Linux 2.3.99-pre6)
              Récupérer  des  informations  sur le signal qui a causé l’arrêt.
              Pour  ce   faire,   copier   une   structure   siginfo_t   (voir
              sigaction(2))  du fils à l’adresse data du père. L’argument addr
              est ignoré.

       PTRACE_SETREGS, PTRACE_SETFPREGS
              Remplir les registres  généraux  ou  du  processeur  en  virgule
              flottante,  depuis  le  contenu de l’adresse data du père. Comme
              pour PTRACE_POKEUSER certaines  modifications  sont  interdites.
              (addr est ignoré).

       PTRACE_SETSIGINFO (depuis Linux 2.3.99-pre6)
              Fixer   des   informations  de  signaux.  Copier  une  structure
              siginfo_t de l’adresse data dans le  père  vers  le  fils.  Cela
              n’affecte  que les signaux qui auraient dû être délivrés au fils
              et ont été  interceptés  à  cause  de  ptrace().  Il  peut  être
              difficile  de  différencier  ces  signaux  normaux  des  signaux
              générés par ptrace() lui-même. L’argument addr est ignoré.

       PTRACE_SETOPTIONS (depuis Linux 2.4.6, voir remarques dans BOGUES)
              Fixe les options de ptrace à partir de l’adresse  data  dans  le
              père  (addr  est  ignoré).  data  est interprété comme un masque
              d’options, qui est construit à partir des drapeaux suivants :

              PTRACE_O_TRACESYSGOOD (Depuis Linux 2.4.6)
                     Lors d’un appel système, mettre à 1 le bit 7 du numéro de
                     signal  (envoyer  SIGTRAP|0x80). Cela permet au processus
                     utilisant ptrace()  de  faire  la  différence  entre  une
                     trappe  normale,  et  une  trappe due à un appel système.
                     PTRACE_O_TRACESYSGOOD peut ne pas marcher sur toutes  les
                     architectures.

              PTRACE_O_TRACEFORK (depuis Linux 2.5.46)
                     Arrêter  le  fils  au  prochain  fork(2)  avec  SIGTRAP |
                     PTRACE_EVENT_FORK << 8  et  commencer  automatiquement  à
                     suivre  le  nouveau processus créé, qui démarrera avec un
                     signal SIGSTOP. Le PID du  nouveau  processus  peut  être
                     récupéré avec PTRACE_GETEVENTMSG.

              PTRACE_O_TRACEVFORK (depuis Linux 2.5.46)
                     Arrêter le fils au prochain appel vfork(2) avec SIGTRAP |
                     PTRACE_EVENT_VFORK << 8 et  commencer  automatiquement  à
                     suivre  le  nouveau processus créé, qui démarrera avec un
                     signal SIGSTOP. Le PID du  nouveau  processus  peut  être
                     obtenu avec PTRACE_GETEVENTMSG.

              PTRACE_O_TRACECLONE (depuis Linux 2.5.46)
                     Arrêter le fils au prochain appel clone(2) avec SIGTRAP |
                     PTRACE_EVENT_CLONE << 8 et  commencer  automatiquement  à
                     suivre  le nouveau processus cloné, qui démarrera avec un
                     signal SIGSTOP. Le PID du  nouveau  processus  peut  être
                     obtenu  avec PTRACE_GETEVENTMSG. Cette option peut ne pas
                     intercepter tous les appels clone(2). Si le fils  appelle
                     clone(2)  avec l’attribut CLONE_VFORK, PTRACE_EVENT_VFORK
                     sera envoyé si PTRACE_O_TRACEVFORK est utilisé. Sinon, si
                     le  fils  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  le fils au prochain appel execve(2) avec SIGTRAP
                     | PTRACE_EVENT_EXEC << 8.

              PTRACE_O_TRACEVFORKDONE (depuis Linux 2.5.60)
                     Arrêter le fils  à  la  fin  du  prochain  vfork(2)  avec
                     SIGTRAP | PTRACE_EVENT_VFORK_DONE << 8.

              PTRACE_O_TRACEEXIT (depuis Linux 2.5.60)
                     Arrêter   le   fils  à  sa  terminaison  avec  SIGTRAP  |
                     PTRACE_EVENT_EXIT << 8. Le code de retour  du  fils  peut
                     être  obtenu  avec  PTRACE_GETEVENTMSG.  Cet  arrêt  sera
                     effectué 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’appelant ne peut pas empêcher
                     la terminaison du fils.

       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 dans le père. Pour PTRACE_EVENT_EXIT,  il  s’agit
              du   code   de   retour   du   fils.   Pour   PTRACE_EVENT_FORK,
              PTRACE_EVENT_VFORK et PTRACE_EVENT_CLONE, il s’agit  du  PID  du
              nouveau  processus.  Depuis  Linux  2.6.18,  le  PID  du nouveau
              processus est également disponible pour PTRACE_EVENT_VFORK_DONE.
              (addr est ignoré.)

       PTRACE_CONT
              Redémarrer  le  processus  fils  arrêté.  Si data est non nul et
              autre que SIGSTOP, il est interprété comme un numéro de signal à
              délivrer  au  fils;  sinon  aucun  signal n’est délivré. On peut
              ainsi contrôler si un  signal  envoyé  au  fils  doit  lui  être
              délivré ou non (addr est ignoré).

       PTRACE_SYSCALL, PTRACE_SINGLESTEP
              Redémarrer le processus fils 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. (Le fils sera aussi arrêté  par  l’arrivée  d’un
              signal).  Du  point de vue du père, le fils 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_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é.   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 du fils. Le paramètre data est
              interprété comme pour PTRACE_CONT. (addr est ignoré ; cet  appel
              n’est pas disponible sur toutes les architectures.)

       PTRACE_KILL
              Envoyer  au  fils  un  signal SIGKILL pour le terminer. (addr et
              data sont ignorés).

       PTRACE_ATTACH
              Attacher  le  processus  numéro  pid,   pour   le   suivre.   Le
              comportement  du  fils  est  le  même  que  s’il  avait  fait un
              PTRACE_TRACEME. Le processus appelant devient alors le père pour
              de nombreuses choses (il recevra les notifications d’événements,
              et sera indiqué comme le père dans un  ps(1)).  Mais  getppid(2)
              renverra  dans le fils le PID du vrai père. Le processus fils va
              recevoir un SIGSTOP, mais il ne sera peut-être pas  stoppé  tout
              de suite, utilisez wait(2) pour attendre son arrêt (addr et data
              sont ignorés).

       PTRACE_DETACH
              Relancer un processus fils comme avec PTRACE_CONT, en commençant
              par  le  détacher,  ce  qui  annule  les effets de changement de
              parenté de PTRACE_ATTACH et les  effets  de  PTRACE_TRACEME.  Le
              processus  ne  sera plus suivi. Bien que cela soit involontaire,
              sous Linux un processus suivi peut être  détaché  ainsi  quelque
              soit  la  méthode  employée  pour  démarrer  le suivi. (addr est
              ignoré).

VALEUR RENVOYÉE

       Pour les requêtes PTRACE_PEEK*, ptrace() renvoie la valeur réclamée  et
       zéro  pour  les  autres  requêtes,  ou -1 en cas d’échec en remplissant
       errno avec le code d’erreur. Comme la valeur renvoyée par  une  requête
       PTRACE_PEEK* peut légitimement être -1, il faut vérifier errno après un
       tel appel pour vérifier si une erreur s’est produite.

ERREURS

       EBUSY  (i386 seulement) Il y a eu une erreur 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 invalide du
              processus fils ou  du  père,  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 invalide.

       EIO    La  requête request n’est pas valide ou une tentative de lecture
              ou d’écriture dans une zone invalide de mémoire a  eu  lieu.  Il
              peut   également  y  avoir  un  problème  d’alignement  sur  une
              frontière de mot, ou une tentative de redémarrage en envoyant un
              signal invalide.

       EPERM  Le processus indiqué ne peut pas être suivi. Cela peut être dû à
              un manque de privilège du parent  (la  capacité  nécessaire  est
              CAP_SYS_PTRACE).  Les  processus  non-root ne peuvent pas suivre
              les processus auxquels ils ne peuvent envoyer de signal, ou ceux
              qui  s’exécutent  Set-UID/Set-GID.  En  outre, le processus visé
              peut être déjà suivi, ou être init(8) (pid 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 en ont
              besoin).

CONFORMITÉ

       SVr4, BSD 4.3.

NOTES

       Bien que les arguments de ptrace() soient  interprétés  comme  dans  le
       prototype  plus  haut,  la  bibliothèque glibc déclare ptrace comme une
       fonction variadique où seul l’argument request est fixé. Ceci  signifie
       que  les  arguments  finaux  inutiles  peuvent être omis, bien que cela
       utilise un comportement non documenté de gcc(1).

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

       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, etc.)

       Le  suivi  peut  engendrer   des   modifications   subtiles   dans   le
       fonctionnement  du  processus. Par exemple, si un processus est attaché
       avec PTRACE_ATTACH,  son  père  original  ne  peut  plus  recevoir  les
       notifications avec wait(2) lorsqu’il s’arrête, et il n’y a pas de moyen
       de simuler cette notification.

       Lorsque le parent reçoit un événement avec  PTRACE_EVENT_*  activé,  le
       fils  n’est  pas dans la procédure normale de réception de signal. Cela
       signifie que le parent ne peut pas exécuter ptrace(PTRACE_CONT) avec un
       signal  ou  ptrace(PTRACE_KILL).  kill(2)  avec  un signal SIGKILL peut
       cependant être utilisé pour tuer le processus fils à la réception  d’un
       de ces messages.

       Cette  page  documente le fonctionnement actuel de ptrace() sous Linux.
       Celui-ci peut varier sensiblement sur 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.

       La page de manuel de SunOS  décrit  ptrace()  comme  un  appel  système
       «unique  and  arcane », ce qu’il est. Le mécanisme de débogage basé sur
       le système proc, présent dans Solaris 2 implémente un  surensemble  des
       fonctionnalités de ptrace() de manière plus puissante et plus uniforme.

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 ces en-têtes 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.

VOIR AUSSI

       gdb(1),  strace(1),  execve(2),  fork(2),  signal(2), wait(2), exec(3),
       capabilities(7)

COLOPHON

       Cette page fait partie de  la  publication  3.23  du  projet  man-pages
       Linux.  Une description du projet et des instructions pour signaler des
       anomalies      peuvent      être       trouvées       à       l’adresse
       http://www.kernel.org/doc/man-pages/.

TRADUCTION

       Cette  page  de  manuel  a  été  traduite et mise à jour par Christophe
       Blaess <http://www.blaess.fr/christophe/> entre 1996 et 2003, puis  par
       Alain  Portal  <aportal AT univ-montp2 DOT fr> jusqu’en 2006, et mise à
       disposition sur http://manpagesfr.free.fr/.

       Les mises à jour et corrections de la version présente dans Debian sont
       directement gérées par Julien Cristau <jcristau@debian.org> et l’équipe
       francophone de traduction de Debian.

       Veuillez  signaler  toute  erreur   de   traduction   en   écrivant   à
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous pouvez toujours avoir accès à la version anglaise de  ce  document
       en utilisant la commande « man -L C <section> <page_de_man> ».