Recherche sur le site Web

Comment tracer les appels système effectués par un processus avec Strace sur Linux


Il y a des moments où il est utile d'inspecter ce que fait une application en cours d'exécution sous le capot, et quel système appelle qu'il effectue pendant son exécution. Pour accomplir une telle tâche sur Linux, nous pouvons utiliser l'utilitaire strace . Dans cet article, nous verrons comment l'installer et nous apprendrons son utilisation de base.

Dans ce tutoriel, vous apprendrez :

  • Comment installer Strace
  • Comment utiliser Strace pour tracer les appels système faits par un processus
  • Comment filtrer les spécificités des appels système
  • 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 sur Linux

Exigences et conventions logicielles utilisées

Installation

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

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

$ sudo dnf install strace

Si nous sommes plus à l'aise d'utiliser 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 référentiel extra :

$ sudo pacman -S strace

Avec le logiciel installé, nous pouvons avancer 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 et les 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 (descripteur de fichier d'erreur standard).

Voyons une utilisation de base de strace , afin de se familiariser avec sa sortie. Dans son utilisation la plus élémentaire, nous appelons Strace suivi du programme que nous voulons exécuter et du comportement que nous voulons analyser. Pour le bien de cet exemple, nous ne copierons que un fichier à l'aide de la commande cp :

$ strace cp ~/.bashrc bashrc

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

  • Le nom d'appel système
  • Les arguments transmis à l'appel du système entre parenthèses
  • La valeur de retour d'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 d'arguments spécifié. Le premier argument accepté par execv est le chemin du fichier que nous voulons exécuter; Le second est un éventail de chaînes qui représente les arguments qui seront transmis au programme (le premier argument, par convention, étant le nom du programme lui-même).

Dans notre cas, comme prévu, le binaire appelé est /usr/bin/cp , et le tableau d'arguments transmis à l'appel est: le nom du programme (CP), la source et Les chemins de destination:

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

La notation /* 46 vars */ signifie que 46 variables où hérité du processus d'appel (dans la fonction execv L'environnement est tiré du ENVIRON variable). Enfin, nous avons la valeur de retour , qui dans ce cas est 0 (en fait la famille exec de fonction renvoie une valeur uniquement si une erreur se produit ).

Filtrage uniquement les appels système spécifiques

Lorsque vous utilisez Strace , nous pouvons parfois vouloir suivre uniquement les appels du 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 nous avons utilisée dans l'exemple précédent, mais nous voulons que les appels système lisent s'affichent dans la sortie, nous exécuterons:

$ strace -e read cp ~/.bashrc bashrc

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

La sortie de la commande "Strace -e Read Cp ~/.Bashrc Bashrc" ="Font-Size: hheRit;"> L'appel système prend trois arguments: le premier est un File Descriptor associé au fichier qui doit être lu; Le second est le tampon dans lequel le fichier doit être lu, et le troisième est le Nombre d'octets qui devrait être lu. Au cours du succès, la fonction renvoie le nombre d'octets lire dans le fichier, comme nous pouvons observer dans la sortie de ce qui précède.

Attacher Strace sur un processus de course

Jusqu'à présent, nous avons invoqué Strace qui lui a transmis la commande à exécuter et de garder la trace de; Et si nous voulons retracer un processus existant et déjà en cours d'exécution? Dans ce cas, nous devons invoquer strace avec l'option -p (ou - joignez ) et passez la pid (ID de processus) du processus auquel nous voulons le fixer.

Pour trouver le PID d'un programme, parmi les autres solutions, nous pouvons utiliser l'utilitaire pidof . Pour le bien de cet exemple, nous attacherons 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 du serveur gnome-terminal. Sachant cela, nous pouvons attacher strace au processus:

$ strace -p 121316

La commande ci-dessus renverra initialement quelque chose comme:

La sortie de la commande «Strace -P 121316» La sortie ci-dessus (tronquée) sera mise à jour «à la volée» lorsque les appels système sont effectués. Pour «détacher» strace Nous pouvons simplement appuyer sur Ctrl + c sur le clavier; Nous serons informés de le "détachement", mais le processus tracé continuera à fonctionner:

strace: Process 121316 detached

Signaux de traçage

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

$ top

Nous lui attachons strace , après avoir obtenu son pid, qui dans ce cas est 44825 :

$ strace -p 44825

À ce stade, strace commence à suivre les appels du système effectués par top , mais aussi les signaux reçus par lui. Pour le prouver, nous envoyons un sigterm à 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 livrés (SIGTERM=15), si_code contient un code qui identifie la cause du signal (si_user=0): en Ce cas le signal a été généré par un processus utilisateur. Les champs si_pid et si_uid rapportent 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 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 regarder la mise à jour dans le fichier, nous pouvons utiliser le queue : Normalement, cette commande lit les 10 dernières lignes d'un fichier et sort, mais si nous l'appelons avec le -f Option (abréviation de - Suivez ) Nous pouvons observer que le nouveau contenu est annexé:

$ tail -f strace_output

Imprimez un résumé des appels du 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 passés par un processus spécifié. Si nous voulons générer un tel rapport, tout ce que nous avons à faire est d'invoquer le programme avec l'option -c ou - Résumé uniquement . Prenons comme exemple la commande cp que nous avons utilisée auparavant:

$ 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, puisque 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é mais toujours obtenir la sortie régulière du programme, nous devons utiliser l'option -c à la place, qui est la forme courte de - résumé .

Conclusions

Dans ce didacticiel, nous avons appris à installer et à utiliser Strace , une belle utilité 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 du système, comment attacher strace à un processus déjà en cours d'exécution et comment Les signaux reçus par un processus sont informés; Enfin, nous avons vu comment générer un résumé de tous les appels passés par un processus. Ici, nous avons à peine rayé 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: