Ich habe einen modernen Linux-Desktop mit vielen gleichzeitig laufenden Prozessen. Einer dieser Prozesse, und ich weiß nicht welcher, ruft eine Funktion some_func
auf aus einer beliebten dynamischen Bibliothek some_lib
(denken Sie an libc
oder libx11
, also viel der Prozesse verwenden es), und ich möchte wissen, welcher Prozess das tut (und idealerweise einen Stack-Trace von jedem Aufruf haben).
Wie bestimme ich, welcher Prozess some_lib
aufruft ?
Optionen, die ich bisher in Betracht gezogen habe:
- Verwenden Sie
ltrace
oderlatrace
:Einenltrace
haben -Stil detaillierte Liste
dessen, welcher Prozess die Funktion aufgerufen hat, an der ich interessiert bin, mit welchen
Argumenten wäre perfekt, aberltrace
funktioniert nur mit
einzelnen Prozessen oder Prozessgruppen. Ich kann nicht einfachltrace -e
eingeben und sehen Sie alle systemweiten Verwendungen.
[email protected]_lib -fp 1 - Finden Sie mit
lsof
heraus, welche Prozesse meine Bibliothek verwenden , fahren Sie dann mit Schritt 1 fort:Das wäre sehr umständlich, da es zu viele Prozesse gibt, die dieselbe Bibliothek verwenden, aber diese Funktion nicht aufrufen. grep -r some_func /usr
, dann sehen Sie, ob es nur ein paar Binärdateien gibt, die die Funktion aufrufen können, und arbeiten Sie sich von dort aus vor. Obwohl das könnte in einigen begrenzten Fällen funktionieren, ist dies keinesfalls eine allgemeine Lösung und würde nicht funktionieren, wenn z.some_func
ist in verschiedenen Binärdateien allgegenwärtig, wird aber selten aufgerufen.- Verwenden Sie das Kernel-Audit-System. Wenn ich einen Systemaufruf verfolgen würde, könnte ich
auditctl -S some_syscall ...
eingeben und das würde den Zweck erfüllen, systemweite Aufrufe zu protokollieren. Jedochauditctl
scheint nicht in der Lage zu sein, die gleiche Granularität mit Bibliotheksfunktionen zu erreichen . - Endlich konnte ich umbauen die Bibliothek, indem Sie der Funktion, an der ich interessiert bin, eine neue Zeile hinzufügen, die alle ihre Aufrufe protokollieren würde. Während dies mein Problem garantiert lösen würde, wäre diese Lösung umständlich und erfordert das Ändern/Neukompilieren der Bibliothek und mindestens zwei Neustarts, um die instrumentierte Bibliothek auszurollen und sie zurückzusetzen, nachdem der Übeltäter gefunden wurde.
Gibt es einen einfacheren Weg?
(Ich möchte darauf hinweisen, dass dies eine allgemeine Frage sein soll und hauptsächlich an allgemeinen Lösungen interessiert bin, die einfach funktionieren würden.)
Ich habe einen netten Vergleichsartikel gefunden, in dem ein paar weitere Suchfunktionen erwähnt werden, die ich nicht kannte und die es vielleicht wert sind, erkundet zu werden.
Akzeptierte Antwort:
SystemTap mit debuginfo kann Funktionsaufrufe in Bibliotheken verfolgen; auf einem Centos 7-System:
$ sudo stap -L 'process("/lib64/libglib*").function("*strndup*")'
process("/usr/lib64/libglib-2.0.so.0.5000.3").function("g_strndup")
$
Und dies kann als probe
verwendet werden Punkt, der Backtraces ausgibt oder was auch immer Sie wollen, das mit SystemTap geschrieben werden kann:
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())
}
gespeichert als probelibraryfunc.stp
Dies kann über
$ sudo stap probelibraryfunc.stp
kann aber wahnsinnig viel Output produzieren, wenn der Aufruf üblich ist…
Verwandte:Ist es möglich, Open Office über STDIN zu füttern?