PTRACE
Section: Manuel du programmeur Linux (2) Updated: 18 juillet 2003 Index
NOM
SYNOPSIS
DESCRIPTION
NOTES
VALEUR RENVOYÉE
ERREURS
CONFORMITÉ
VOIR AUSSI
TRADUCTION
NOM
ptrace - Suivre un processus.
SYNOPSIS
#include <sys/ptrace.h>
long ptrace(enum __ptrace_request requête, int pid, void * addr, int 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ébugging.
Le père peut démarrer un suivi en appelant
fork(2)
et que le fils créé face 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. Le parent doit être en attente
de suivi du fils. Tout signal (sauf SIGKILL) reçu par le processus l'arrêtera,
et le père sera notifié grâce à
wait.
De plus, les appels-ultérieurs à
exec
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_PEEKUSR
-
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é 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 (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_POKEUSR
-
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_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_POKEUSR certaines
modifications sont interdites. (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. (add est ignoré).
- 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
pour attendre son arrêt (addr et data sont ignorés).
- PTRACE_DETACH
-
Relancer un processus fils comme avec PTRACE_CONT, en commençant pas le détacher,
ce qui rétablit sa parenté originale. Le processus ne sera plus suivi.
Bien que cela soit involontaire, sous Linux un processus suivi peut être
être détaché ainsi quelque soit la méthode employée pour démarrer le suivi.
(addr est ignoré).
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 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.
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
lorsqu'il s'arrête, et il n'y a pas de moyen de simuler cette notification.
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 sur-ensemble des fonctionnalités de
ptrace
de manière plus puissante et plus uniforme.
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
- EPERM
-
Le processus indiqué ne peut pas être suivi. Cela peut être dû à un manque de privilège du
parent. 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
(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).
- 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.
- EFAULT
-
Tentative de lire ou écrire dans une zone mémoire invalide du processus ou
du père. Malheureusement sous Linux, certaines variantes de cette erreur
déclencheront EIO ou EFAULT plus ou moins arbitrairement.
CONFORMITÉ
SVr4, SVID EXT, AT&T, X/OPEN, BSD 4.3
VOIR AUSSI
TRADUCTION
Christophe Blaess, 1996-2003.
|