PTRACE
Section : Manuel du programmeur Linux (
2)
Mise à jour de la version anglaise : 21 mai 2008
Index
Menu principal
NOM
ptrace - Suivre un processus
SYNOPSIS
#include <sys/ptrace.h>
long ptrace(enum __ptrace_request requête, pid_t pid,
void *addr, void *data);
DESCRIPTION
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
requête
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.
(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
<linux/user.h>
et
<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.
Voir 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
<linux/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 provoqué l'arrêt.
Copier une structure
siginfo_t
(voir
sigaction(2))
du fils vers
data
du père.
(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)
-
Configurer les informations du signal.
Copier une structure
siginfo_t
de l'emplacement
data
dans le père vers le fils.
Cela n'affecte que les signaux qui auraient dû normalement être délivrés
au fils et ont été interceptés par le traceur.
Il peut être difficile de différencier ces signaux normaux
des signaux synthétiques générés par
ptrace()
lui-même.
(addr
est ignoré.)
- PTRACE_SETOPTIONS (depuis Linux 2.4.6 ;
-
voir les remarques dans la section BOGUES)
Configure les options ptrace pour l'adresse
data
dans le père
(addr
est ignoré).
data
est interprété comme un masque de bits d'options qui est
construit à partir des attributs suivants :
-
- PTRACE_O_TRACESYSGOOD (depuis Linux 2.4.6)
-
Lors de la délivrance de déroutements syscall, mettre à 1 le bit 7
dans le numéro de signal (c'est-à-dire, délivrer
SIGTRAP | 0x80) .
Le traceur peut ainsi indiquer plus facilement la différence entre
les déroutements normaux et ceux provoqués par un syscall.
(PTRACE_O_TRACESYSGOOD
peut ne pas fonctionner sur toutes les architectures.)
- PTRACE_O_TRACEFORK (depuis Linux 2.5.46)
-
Arrêter le fils au prochain appel
fork(2)
avec
SIGTRAP | PTRACE_EVENT_FORK << 8
et démarrer automatiquement le suivi
du nouveau processus « forké » qui démarrera avec un signal
SIGSTOP.
Le PID du nouveau processus peut être obtenu 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 démarrer automatiquement le
suivi du nouveau processus « vforké » qui démarrera avec un
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 démarrer automatiquement
le suivi du nouveau processus « cloné » qui démarrera avec un
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 délivré à la place
si
PTRACE_O_TRACEVFORK
est utilisé ; autrement, si le fils appelle
clone(2)
avec le signal de sortie configuré à
SIGCHLD,
PTRACE_EVENT_FORK
sera délivré 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 appel
vfork(2)
avec
SIGTRAP | PTRACE_EVENT_VFORK_DONE << 8.
- PTRACE_O_TRACEEXIT (depuis Linux 2.5.60)
-
Arrêter le fils à la sortie avec
SIGTRAP | PTRACE_EVENT_EXIT << 8.
La valeur de retour du fils peut être obtenu avec
PTRACE_GETEVENTMSG.
Cet arrêt sera effectué plutôt pendant le processus de sortie
lorsque les registres sont encore disponibles,
permettant au traceur de voir où survient la sortie,
alors que la notification de sortie normale est effectuée après
que le processus ait achevé sa sortie.
Bien que le contexte soit disponible,
le traceur ne peut pas empêcher la sortie d'arriver à ce moment-là.
- PTRACE_GETEVENTMSG (depuis Linux 2.5.46)
-
Obtenir un message (sous la forme d'un
unsigned long)
d'un événement ptrace qui vient juste d'arriver, le mettre à l'emplacement
data
du 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,
c'est le 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
n'est pas 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.
(add
est ignoré).
- PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP (depuis Linux 2.6.14)
-
Pour
PTRACE_SYSEMU,
continuer et s'arrêter au prochain syscall
qui ne sera pas exécuté.
Pour
PTRACE_SYSEMU_SINGLESTEP,
faire la même chose mais en pas-à-pas s'il n'y a pas de syscall.
Cet appel est utilisé par des
programmes comme « User Mode Linux » qui veulent émuler tous les syscall
du fils
(addr
et
data
sont ignorés ; pas supporté 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 annulle les effets de changements 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
-
Une tentative a été faite d'utiliser une option invalide.
- EIO
-
La
requête
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-superutilisateur 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 de
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 du signal.
Cela signifie que le parent ne peut pas effectuer un
ptrace(PTRACE_CONT)
avec un signal ou
ptrace(PTRACE_KILL).
On peut utiliser
kill(2)
avec un signal
SIGKILL
plutôt que de tuer le processus fils
après 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 avec des entêtes du noyau 2.6,
PTRACE_SETOPTIONS
est déclarée avec une valeur différente de celle du noyau 2.4.
Cela conduit à ce que les applications compilées avec ces entêtes
ne peuvent pas s'exécuter sur les noyaux 2.4.
Cela peut être contourné 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)
TRADUCTION
Ce document est une traduction réalisée par Christophe Blaess
<http://www.blaess.fr/christophe/> le 12 octobre 1996
et révisée le 23 juin 2008.
L'équipe de traduction a fait le maximum pour réaliser une adaptation
française de qualité. La version anglaise la plus à jour de ce document est
toujours consultable via la commande : « LANG=C man 2 ptrace ».
N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute
erreur dans cette page de manuel.
Index
- NOM
-
- SYNOPSIS
-
- DESCRIPTION
-
- VALEUR RENVOYÉE
-
- ERREURS
-
- CONFORMITÉ
-
- NOTES
-
- BOGUES
-
- VOIR AUSSI
-
- TRADUCTION
-
Dernière mise à jour : 17 juillet 2008