Ho un desktop Linux moderno con molti processi in esecuzione contemporaneamente. Uno di quei processi, e non so quale, chiama una funzione some_func da una popolare libreria dinamica some_lib (pensa a libc o libx11 , quindi un molto di processi lo usa) e voglio sapere quale processo lo fa (e idealmente, avere una traccia dello stack di ogni invocazione).
Come faccio a determinare quale processo effettua una chiamata a some_lib ?
Opzioni che ho considerato finora:
- Usa
ltraceolatrace:Avere unlatrace-style elenco dettagliato
di quale processo ha chiamato la funzione che mi interessa con quali
argomenti sarebbero perfetti, maltracefunziona solo con un
singolo processo o gruppi di processi. Non posso semplicemente digitareltrace -ee vedere tutti gli usi a livello di sistema.
[email protected]_lib -fp 1 - Trova quali processi utilizzano la mia libreria con
lsof, quindi procedi con il passaggio 1:sarebbe molto ingombrante, poiché ci sono troppi processi che utilizzano la stessa libreria, ma non chiamano tale funzione. grep -r some_func /usr, quindi controlla se ci sono solo un paio di binari in grado di chiamare la funzione e procedi da lì. Anche se potrebbe funziona in un numero limitato di casi, questa non è affatto una soluzione generale e non funzionerebbe se ad es.some_funcè onnipresente in vari binari ma è chiamato raramente.- Usa il sistema di controllo del kernel. Se stavo tracciando una chiamata di sistema, potrei digitare
auditctl -S some_syscall ...e questo farebbe il trucco per registrare le invocazioni a livello di sistema. Tuttavia,auditctlnon sembra essere in grado di fare lo stesso livello di granularità con le funzioni di libreria . - Finalmente, ho potuto ricostruire la libreria, aggiungendo una nuova riga alla funzione che mi interessa che registrerebbe tutte le sue invocazioni. Anche se questo sarebbe garantito per risolvere il mio problema, quella soluzione sarebbe ingombrante e richiederebbe la modifica/ricompilazione della libreria e almeno 2 riavvii per implementare la libreria strumentata e ripristinarla dopo aver trovato il colpevole.
C'è un modo più semplice?
(Voglio sottolineare che questa è intesa come una domanda generale e sono principalmente interessato a soluzioni generali che funzionerebbero.)
Ho trovato un bell'articolo di confronto che menziona alcune altre strutture di tracciamento di cui non ero a conoscenza, che potrebbe valere la pena esplorare.
Risposta accettata:
SystemTap con debuginfo può tracciare le chiamate di funzione nelle librerie; su un sistema Centos 7:
$ sudo stap -L 'process("/lib64/libglib*").function("*strndup*")'
process("/usr/lib64/libglib-2.0.so.0.5000.3").function("g_strndup")
$
E questo può essere usato come probe punto che stampa backtrace o qualsiasi cosa tu voglia che può essere scritta con 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())
}
salvato come probelibraryfunc.stp questo può essere eseguito tramite
$ sudo stap probelibraryfunc.stp
anche se può produrre quantità pazze di output se la chiamata è comune...
Correlati:È possibile alimentare Open Office tramite STDIN?