Trova dove è definito un simbolo di libreria condivisa su un sistema live / elenca tutti i simboli esportati su un sistema


21

Fondamentalmente, si tratta di due domande in una: perché se posso elencare tutti i simboli esportati all'interno di un sistema, insieme al loro percorso di libreria condiviso, allora potrei semplicemente grepquell'output.

Per i simboli del kernel, immagino che sia un po 'più semplice, perché possiamo sempre cat /proc/kallsymse ottenere un elenco di tutti i simboli di quei moduli caricati in memoria; quindi sudo cat /proc/modulesfornirà un elenco di moduli caricati con i loro indirizzi, ma non i percorsi da cui sono stati caricati i moduli (se sono costruiti come oggetti .ko separati, fuori dall'albero)

Ad esempio, provo a tracciare il programma kstusando ltrace:

$ ltrace kst2
...
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0, 0xbfe631a8, 0x823652b, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298)     = 0xa1ce800
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298)     = 0xa1ce800
...

... e vorrei sapere dove _ZNK13QGraphicsItem10parentItemEvrisiede.

Quindi, cosa fare con i simboli della libreria condivisa? Leggere attraverso [gcc-help] Ri: trovare la libreria in cui è definito il simbolo. ; Ho provato qualcosa del genere:

$ find /usr/lib -name '*.so*' -exec nm --print-file-name --defined-only --dynamic {} \; | grep "QGraphicsItem"
...
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
/usr/lib/libQtGui.so.4.7.2:00766aa0 T _Zls6QDebugN13QGraphicsItem18GraphicsItemChangeE
/usr/lib/libQtGui.so.4.7.2:00767e80 T _Zls6QDebugP13QGraphicsItem
...

... ma questo mi dà ulteriori problemi: non conosco davvero tutti i percorsi che sono scansionati per le librerie condivise sul mio sistema, quindi quando ho provato per la prima find /lib ...volta non ha trovato nulla; Trovo questa supposizione di directory fastidiosa, così come l'alternativa: scansionare l'intero filesystem di root con find... E inoltre, mi sembra di colpire * .so che non può essere aperto da nm(forse perché sono collegamenti simbolici?), Che emette un bel po 'di messaggi di errore (che non mi piacciono neanche).

Il fatto è che ldd(o ld?) Probabilmente esegue alcune di queste ricerche di simboli, ma ho provato le rispettive manpage e non riesco a vedere un modo per "trovare" alcun simbolo dalla riga di comando, senza fornire una sorta di file eseguibile come un discussione. Domanda a margine: ci sarebbe un modo per usare questi strumenti per quello?

Quindi, quello che sto cercando uno strumento da riga di comando, che si comporterebbe in qualche modo (pseudocodice):

$ ./findsymbol '_Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE'
symbol found in:
    /usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
...

... dove non specifico alcuna directory da cercare - ma che gestisca anche, ad esempio LD_PRELOADo LD_LIBRARY_PATH; dire se lo faccio:

$ LD_PRELOAD="/path/to/mylib.so" ./findsymbol '*mylib_print*'

... poi otterrei il punto in /path/to/mylib.socui è stato definito il simbolo dato (dato che un tale simbolo non esisterebbe nelle librerie standard) e altrimenti produrrebbe "non trovato". E altrimenti, ./findsymbol --dumpallpotrebbe produrre un elenco di tutti i simboli disponibili e le loro posizioni viste da un determinato ambiente (ad esempio una bashshell specifica ).

Esiste uno strumento come questo per Linux?

Risposte:


16

I percorsi in cui cercare le librerie verranno elencati nel file /etc/ld.so.conf, nella variabile d'ambiente LD_LIBRARY_PATHe in tutti gli RPATH codificati nel binario ELF. Il programma lddti dirà quali librerie verranno caricate da un'applicazione specifica.

Una volta che hai un simbolo di cui sei curioso, puoi usare il programma nmper scaricare simboli .oe .afile e readelfper scaricare simboli da un .soo qualsiasi altro eseguibile elfo.

Esempi:

nm -g /usr/lib/blah.a
readelf -Ws /usr/lib/blah.so

E infine, a parte questo sfondo, ecco il tuo santo graal:

Dato un simbolo _ZN6Kopete6Global10PropertiesC2Ev, dov'è questo?

scanelf -l -s _ZN6Kopete6Global10PropertiesC2Ev | grep _ZN6Kopete6Global10PropertiesC2Ev

che produce:

ET_DYN _ZN6Kopete6Global10PropertiesC2Ev /usr/lib64/libkopete.so.4.11.4

La -lbandiera dice di cercare le directory /etc/ld.so.confe -sspecifica il simbolo da trovare.


Questo è incompleto: alcuni programmi caricano librerie da directory specifiche dell'applicazione.
Gilles 'SO- smetti di essere malvagio' il

2
@Gilles scanelfti consente di specificare directory specifiche in cui cercare e supportare la ricerca ricorsiva in -rmodo da poter modificare i suoi percorsi di ricerca o cercare l'intero sistema senza troppi problemi. Ad esempio scanelf -r -s SYMBOL /lib/* /usr/* /opt/*, troverà la maggior parte dei luoghi nascosti dalle biblioteche.
Casey,

7

Sui sistemi GNU (quando si utilizza il linker dinamico GNU libc), è possibile eseguire il programma come:

LD_DEBUG=bindings kst2

Per trovare dove si risolvono i simboli.


0

Mi sono imbattuto in questo un numero di volte, cercando di trasferire il codice da un sistema Linux a un altro. Di solito finisco per visualizzare tutte le directory standard. Non sono riuscito a trovare nulla su Google. Quindi ecco una breve sceneggiatura:

edt11x / findinsharedlibs

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.