J'ai un bureau Linux moderne avec de nombreux processus exécutés simultanément. Un de ces processus, et je ne sais pas lequel, appelle une fonction some_func
à partir d'une bibliothèque dynamique populaire some_lib
(pensez libc
ou libx11
, donc beaucoup des processus l'utilisent), et je veux savoir quel processus fait cela (et idéalement, avoir une trace de pile de chaque invocation).
Comment déterminer quel processus appelle some_lib
?
Options que j'ai envisagées jusqu'à présent :
- Utiliser
ltrace
oulatrace
:Avoir unltrace
-style liste détaillée
de quel processus a appelé la fonction qui m'intéresse avec quels
arguments serait parfait, maisltrace
ne fonctionne qu'avec
un processus individuel ou des groupes de processus. Je ne peux pas simplement taperltrace -e
et voir toutes les utilisations à l'échelle du système.
[email protected]_lib -fp 1 - Trouver quels processus utilisent ma bibliothèque avec
lsof
, puis passez à l'étape 1 :ce serait très fastidieux, car trop de processus utilisent la même bibliothèque, mais n'appellent pas ladite fonction. grep -r some_func /usr
, puis voyez s'il n'y a que quelques binaires capables d'appeler la fonction, et travaillez à partir de là. Bien que cela pourrait fonctionner dans un nombre limité de cas, ce n'est en aucun cas une solution générale et ne fonctionnerait pas si, par exemple,some_func
est omniprésent dans divers binaires mais est rarement appelé.- Utilisez le système d'audit du noyau. Si je traçais un appel système, je pourrais taper
auditctl -S some_syscall ...
et cela ferait l'affaire dans la journalisation des invocations à l'échelle du système. Cependant,auditctl
ne semble pas être capable de faire le même niveau de granularité avec les fonctions de bibliothèque . - Enfin, j'ai pu reconstruire la bibliothèque, en ajoutant une nouvelle ligne à la fonction qui m'intéresse qui enregistrerait toutes ses invocations. Bien que cela soit garanti pour résoudre mon problème, cette solution serait lourde et nécessiterait de modifier/recompiler la bibliothèque et au moins 2 redémarrages pour déployer la bibliothèque instrumentée et la restaurer après avoir trouvé le coupable.
Existe-t-il un moyen plus simple ?
(Je tiens à souligner qu'il s'agit d'une question générale et que je suis principalement intéressé par les solutions générales qui fonctionneraient correctement.)
J'ai trouvé un bel article de comparaison mentionnant quelques autres installations de traçage dont j'ignorais l'existence et qui pourraient valoir la peine d'être explorées.
Réponse acceptée :
SystemTap avec debuginfo peut suivre les appels de fonction dans les bibliothèques ; sur un système Centos 7 :
$ sudo stap -L 'process("/lib64/libglib*").function("*strndup*")'
process("/usr/lib64/libglib-2.0.so.0.5000.3").function("g_strndup")
$
Et cela peut être utilisé comme une probe
point qui imprime les backtraces ou tout ce que vous voulez qui peut être écrit avec SystemTap :
probe begin {
printf("okn")
}
probe process("/usr/lib64/libglib-2.0.so.0.5000.3").function("g_strndup") {
/* printf("%s[%d]n", execname(), pid()) */
print_usyms(ubacktrace())
}
enregistré sous probelibraryfunc.stp
cela peut être exécuté via
$ sudo stap probelibraryfunc.stp
bien que cela puisse produire des quantités folles de sortie si l'appel est commun…
Connexe :Est-il possible d'alimenter Open Office via STDIN ?