Recherche de site Web

Comment tracer les appels système effectués par un processus avec strace sous Linux


Il peut arriver qu’il soit utile d’inspecter ce qu’une application en cours d’exécution fait sous le capot et quels appels système elle exécutent pendant son exécution. Pour accomplir une telle tâche sous Linux, nous pouvons utiliser l’utilitaire strace. Dans cet article, nous allons voir comment l’installer et nous allons apprendre son utilisation de base.

Dans ce tutoriel, vous allez apprendre :

  • Comment installer strace
  • Comment utiliser strace pour tracer les appels système effectués par un processus
  • Comment filtrer des appels système spécifiques
  • Comment s’attacher à un processus déjà en cours d’exécution
  • Comment générer un résumé d’appel système

Comment tracer les appels système effectués par un processus avec strace sous Linux

Configuration logicielle requise et conventions utilisées

Installation

Bien qu’il ne soit pas installé par défaut, l’utilitaire strace est disponible dans les dépôts officiels de toutes les principales distributions Linux ; Cela signifie que nous pouvons l’installer très facilement en utilisant notre gestionnaire de paquets préféré.

Si nous fonctionnons sur Fedora (ou toute autre distribution de la famille Red Hat), par exemple, nous devons utiliser dnf :

sudo dnf install strace

Si nous sommes plus à l’aise avec Debian, ou des distributions basées sur Debian telles que Ubuntu ou Linux Mint, nous pouvons utiliser apt pour obtenir le même résultat :

sudo apt install strace

Si Arch Linux est notre distribution de choix, nous pouvons utiliser pacman pour installer l’application, qui est disponible dans le dépôt supplémentaire :

sudo pacman -S strace

Une fois le logiciel installé, nous pouvons aller de l’avant et voir quelques exemples de son utilisation.

Présentation de strace

Comme nous l’avons déjà dit, strace est un outil utilisé pour garder une trace des appels système effectués par un processus en cours d’exécution et des signaux reçus par celui-ci. Les appels système sont l’interface fondamentale entre une application et le noyau Linux ; Lorsque nous utilisons STRACE, le nom des appels effectués par un processus, ainsi que leurs arguments et valeurs de retour sont affichés sur STDERR (Standard Error File Descriptor).

Voyons une utilisation de base de strace, afin de nous familiariser avec sa sortie. Dans son utilisation la plus basique, nous appelons strace suivi du programme que nous voulons exécuter et du comportement que nous voulons analyser. Pour les besoins de cet exemple, nous allons simplement copier un fichier à l’aide de la commande cp :

strace cp ~/.bashrc bashrc

Le résultat de la commande est assez long, et bien sûr, nous ne pouvons pas l’analyser en détail ici ; Voyons juste la première ligne. Chaque ligne de la sortie strace contient :

  • Le nom de l’appel système
  • Les arguments passés à l’appel système entre parenthèses
  • Valeur de retour de l’appel système

Le premier appel système que nous pouvons voir dans la sortie est execve. Cet appel est utilisé pour exécuter un programme avec un tableau spécifié d’arguments. Le premier argument accepté par execv est le chemin du fichier que l’on veut exécuter ; Le second est un tableau de chaînes de caractères qui représente les arguments qui seront passés au programme (le premier argument, par convention, étant le nom du programme lui-même).

Dans notre cas, comme prévu, le binaire qui est appelé est /usr/bin/cp, et le tableau d’arguments passé à l’appel est : le nom du programme (cp), les chemins source et de destination :

execve("/usr/bin/cp", ["cp", "/home/egdoc/.bashrc", "bashrc"], 0x7fff53d4e4c0 /* 46 vars */) = 0

La notation /* 46 vars */ signifie que 46 variables ont été héritées du processus appelant (dans la fonction execv, l’environnement est tiré de la variable d’environnement externe). Enfin, nous avons la valeur de retour, qui dans ce cas est 0 (en fait, la fonction exec family of ne renvoie une valeur que si une erreur se produit).

Filtrage uniquement des appels système spécifiques

Lorsque nous utilisons strace, nous pouvons parfois vouloir garder une trace uniquement des appels système spécifiques effectués par un processus. Dans ces situations, nous pouvons utiliser l’option -e suivie d’une expression qui indique quels appels système doivent être tracés. Supposons que nous exécutions la même commande que celle utilisée dans l’exemple précédent, mais que nous voulions uniquement que les appels système de lecture soient affichés dans la sortie, nous exécuterions :

strace -e read cp ~/.bashrc bashrc

Comme prévu, seuls les appels de lecture sont signalés :

Le résultat de la commande « strace -e read cp ~/.bashrc bashrc " Au fait, l’appel système read prend trois arguments : le premier est un descripteur de fichier associé au fichier qui doit être lu ; le second est le buffer dans lequel le fichier doit être lu, et le troisième est le nombre d’octets qui doit être lu. En cas de succès, la fonction renvoie le nombre d’octets lu à partir du fichier, comme nous pouvons l’observer dans le résultat ci-dessus.

Attachement de strace sur un processus en cours d’exécution

Jusqu’à présent, nous invoquions strace en lui passant la commande à exécuter et à garder une trace ; Que se passe-t-il si nous voulons tracer un processus existant et déjà en cours d’exécution ? Dans ce cas, nous devons invoquer strace avec l’option -p (ou --attach), et passer le PID (Process Id) du processus auquel nous voulons l’attacher.

Pour trouver le PID d’un programme, parmi les autres solutions, on peut utiliser l’utilitaire pidof. Pour les besoins de cet exemple, nous allons attacher strace à une instance en cours d’exécution de gnome-terminal-server :

pidof gnome-terminal-server
121316

La commande pidof a renvoyé 121316, qui est le PID de gnome-terminal-server. Sachant cela, nous pouvons attacher strace au processus :

strace -p 121316

La commande ci-dessus renverra initialement quelque chose comme :

Le résultat de la commande « strace -p 121316 " Le résultat ci-dessus (tronqué) sera mis à jour « à la volée » au fur et à mesure que les appels système sont effectués. Pour « détacher » strace nous pouvons simplement appuyer sur Ctrl+C sur le clavier ; nous serons avertis de the « detachment », mais le processus tracé continuera à s’exécuter :

strace: Process 121316 detached

Traçage des signaux

Grâce à strace, nous pouvons également observer quand un processus reçoit un signal et comment il y réagit. Permettez-moi de le démontrer. Tout d’abord, nous lançons un processus de longue durée en tant que top, qui est un moniteur de processus :

top

On y attache ensuite strace, après avoir obtenu son PID, qui dans ce cas est 44825 :

strace -p 44825

À ce stade, strace commence à suivre les appels système effectués par top, mais aussi les signaux reçus par celui-ci. Pour le prouver, nous envoyons un SIGTERM au PID 44825 :

kill 44825

Comme prévu, l’événement est signalé dans la sortie strace :

--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=44888, si_uid=1000} ---

Dans la sortie ci-dessus, si_signo est le nombre de signaux délivrés (SIGTERM=15), si_code contient un code qui identifie la cause du signal (SI_USER=0) : dans ce cas, le signal a été généré par un processus utilisateur. Les champs si_pid et si_uid indiquent, respectivement, le PID du processus d’envoi et son UID.

Enregistrer la sortie de strace dans un fichier

Si nous utilisons l’option -o (abréviation de --ouput) lors du lancement de strace, nous pouvons rediriger sa sortie vers un fichier, en passant un chemin comme argument, par exemple :

strace -p 121316 -o strace_output
strace: Process 121316 attached

Le fichier strace_output sera créé et la sortie de strace sera écrite à l’intérieur. Pour surveiller la mise à jour dans le fichier, nous pouvons utiliser la queue : normalement, cette commande lit les 10 dernières lignes d’un fichier et se termine, mais si nous l’appelons avec l’option -f (abréviation de --follow), nous pouvons observer que du nouveau contenu est ajouté :

tail -f strace_output

Imprimer un résumé des appels système

L’utilitaire strace est livré avec une fonctionnalité très utile : la possibilité de générer un résumé de tous les appels système effectués par un processus spécifié. Si nous voulons générer un tel rapport, tout ce que nous avons à faire est d’appeler le programme avec l’option -c ou --summary-only. Prenons l’exemple de la commande cp que nous avons utilisée précédemment :

strace -c cp ~/.bashrc bashrc

La commande ci-dessus générera ce rapport :

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 25.71    0.000298           7        38        13 openat
 19.24    0.000223           4        51           mmap
 11.48    0.000133           4        28           close
  9.92    0.000115          57         2         1 newfstatat
  7.94    0.000092          10         9           mprotect
  6.99    0.000081           3        25           fstat
  2.85    0.000033           3        11           read
  2.76    0.000032          16         2           munmap
  2.50    0.000029          14         2           statfs
  1.90    0.000022          22         1           write
  1.55    0.000018           2         8           pread64
  1.38    0.000016           8         2         1 access
  1.04    0.000012           4         3           brk
  0.78    0.000009           4         2           rt_sigaction
  0.60    0.000007           7         1           futex
  0.52    0.000006           3         2         1 arch_prctl
  0.43    0.000005           5         1           rt_sigprocmask
  0.43    0.000005           5         1           set_tid_address
  0.43    0.000005           5         1           fadvise64
  0.43    0.000005           5         1           set_robust_list
  0.43    0.000005           5         1           prlimit64
  0.26    0.000003           3         1         1 stat
  0.26    0.000003           3         1         1 lseek
  0.17    0.000002           2         1           geteuid
  0.00    0.000000           0         1           execve
------ ----------- ----------- --------- --------- ----------------
100.00    0.001159           5       196        18 total

Comme vous pouvez le voir, depuis que nous avons généré un résumé, la sortie normale de strace n’est pas affichée. Si nous voulons générer le résumé tout en obtenant le résultat régulier du programme, nous devons utiliser l’option -C à la place, qui est la forme abrégée de --summary.

Conclusions

Dans ce tutoriel, nous avons appris à installer et à utiliser strace, un utilitaire intéressant utile à des fins de débogage et plus généralement pour garder une trace des appels système effectués par un processus. Nous avons vu comment la sortie de strace est organisée, comment lancer un programme et garder une trace des appels système qu’il effectue, comment attacher strace à un processus déjà en cours d’exécution et comment les signaux reçus par un processus sont notifiés ; Enfin, nous avons vu comment générer un résumé de tous les appels effectués par un processus. Ici, nous avons à peine effleuré la surface de ce que nous pouvons faire avec strace : si vous voulez en savoir plus, le conseil est, comme toujours, de lire le manuel !

Articles connexes: