Come utilizzare ltrace per tracciare le chiamate della libreria

0
18

Interessante correggere gli errori e i bug della libreria che osservi durante l'installazione di un nuovo fantastico programma su Linux? Dai un'occhiata a questo articolo che mostra come usare ltrace, fornendoti lo strumento necessario per eseguire il debug delle chiamate alla libreria.

Cos'è una Libreria?

La maggior parte delle persone ha familiarità con i file .dll/.DLL (Dynamic Link Libraries) in Windows. L'equivalente Linux è un file .so, un oggetto condiviso, spesso indicato solo come libreria.

Una libreria può essere utilizzata da un'applicazione che consente a quel programma di utilizzare funzionalità al di fuori del suo codice di programma. Ad esempio, un server Web potrebbe voler utilizzare una libreria di I/O su disco scritta dal fornitore del sistema operativo o da un'altra terza parte. È un modo per condividere beni e interessi comuni nella maggior parte, se non in tutti, i sistemi operativi.

Le librerie possono essere caricate dinamicamente in fase di esecuzione (all'avvio del programma chiamante, ad esempio), oppure può essere compilato in un'applicazione/binario di destinazione. Saranno quindi sempre caricati (utilizzati o meno), come parte di, e ogni volta che viene avviata l'applicazione che li ha compilati/integrati.

Per ulteriori informazioni sulle librerie, le loro dipendenze e lo strumento ldd, potresti leggere come lavorare con le dipendenze degli oggetti condivisi in Linux. Lo strumento ldd è un altro strumento utile da avere in qualsiasi toolbox utente Linux più avanzato.

che cos'è ltrace?

Ci sono varie utilità di traccia in Linux, come strace per tracciare chiamate e segnali di sistema e traceroute per tracciare il routing di rete. L'utilità/strumento ltrace tiene traccia di tutte le chiamate alla libreria.

Pubblicità

Se hai letto il nostro lavoro con le dipendenze di oggetti condivisi (libreria) nell'articolo Linux (collegato sopra), avrai già visto come puoi scoprire a quali librerie è collegato un particolare binario utilizzando lo strumento ldd. Lo scopo e la funzionalità di ltrace sono in qualche modo diversi; molto in linea con strace, il comando ltrace traccia tutte le chiamate di libreria che un particolare programma sta effettuando mentre è in esecuzione.

Come strace, possiamo avviare un programma sotto(pensaci come una gerarchia) ltrace. Specifichiamo semplicemente il programma che ltrace dovrebbe avviare come prima opzione per ltrace e ltrace avvierà quel programma per noi e inizierà immediatamente (a un livello superiore) a tenere traccia di tutte le chiamate a qualsiasi libreria (sistema operativo o installato da terze parti).< /p>

Lo fa intercettando e registrando le chiamate alla libreria dinamica effettuate dal programma in esecuzione. Traccia anche tutti i segnali inviati al programma in esecuzione, in modo molto simile a strace (e, se lo si desidera, questa funzionalità può essere disabilitata specificando l'opzione -b o l'equivalente –no-signals di ltrace).

Nota che il termine la dinamica è di notevole importanza qui; ltrace traccerà le chiamate alle librerie esterne (sotto forma di file .so o .a), cioè librerie non compilate direttamente in un programma; librerie dinamiche. Quindi, se hai un binario con librerie statiche (compilate), ltrace non sarà in grado di vedere/tracciare tali chiamate interne.

Installazione < i>ltrace

Per installare ltrace sulla tua distribuzione Linux basata su Debian/Apt (come Ubuntu e Mint), esegui il seguente comando nel tuo terminale:

sudo apt install ltrace

Pubblicità< br>

Per installare ltrace sulla tua distribuzione Linux basata su RedHat/Yum (come RHEL, Centos e Fedora), esegui il seguente comando nel tuo terminale:

sudo yum install ltrace

Uso di ltrace

Impostiamo un piccolo ambiente di test:

sudo apt install tar xz-utils mkdir ~/workspace && cd ~/workspace touch a b c

Qui abbiamo installato tar e xz installando xz-utils (puoi invece usare sudo yum install tar xz se stai usando Centos/RHEL/Fedora). Successivamente abbiamo creato una directory ~/workspace e ci siamo passati dentro. Abbiamo quindi creato tre file vuoti utilizzando il comando touch, vale a dire i file a, b e c.

Iniziamo comprimendo i nostri tre file in un (tar combinato e xzcompresso) archive.tar.xz, mentre esegue lo stesso sotto ltrace e osservando l'output di ltrace:

ltrace tar -hcf –xz archive.tar.xz *

Vediamo solo una piccola quantità di output. Possiamo vedere che il nostro programma è terminato con successo (il file di archivio è stato creato), cioè, stato 0: un codice di uscita 0 significa sempre successo in Linux (sebbene il programma debba avere i codici di uscita implementati correttamente). >Questo non è molto utile fino a questo punto. Ragionare per alcuni secondi su come opererà tar qui rivelerà rapidamente il nostro prossimo approccio. Il lettore avido potrebbe anche aver capito che il comando tar internamente avrebbe chiamato il comando xz. L'opzione –xz passata alla nostra riga di comando tar assicurerà che il programma xz venga utilizzato per la compressione.

Il processo secondario (o il terzo nella gerarchia complessiva) ovvero xz (gerarchia: ltrace > tar > xz) verrà avviato da tar quando necessario. Pertanto, dobbiamo tracciare i processi figlio del programma in esecuzione sotto ltrace, ovvero tar. Possiamo farlo specificando l'opzione follow (-f) per ltrace:

ltrace -f tar -hcf –xz archive.tar.xz * Annuncio

Nota che è importante specificare l'opzione -f direttamente dietro ltrace e non più avanti nella riga di comando dopo tar, ad esempio. Il motivo è che vogliamo specificare questa opzione per ltrace e non per il comando tar. Tutte le opzioni dopo il comando tar sono opzioni specifiche per tar mentre -f è un'opzione specifica per ltrace.

L'output è un po' più interessante. Non osserviamo ancora nessuna chiamata di libreria (di qualsiasi forma), ma almeno vediamo che due sottoprocessi sono fork (nota exec()) e che entrambi i sottoprocessi terminano con lo stato 0. Pratico e tutto bene.

Allora, dove sono le nostre chiamate in biblioteca? Controllando tar e xz (i due programmi che verranno utilizzati dal comando per creare il file di archivio) con ldd, ci rendiamo subito conto che la maggior parte delle librerie utilizzate da entrambi i programmi sono librerie di sistema:

dove è tar dove è xz ldd /bin/tar ldd /usr/bin/xz

Dobbiamo quindi fare un ulteriore passo avanti e abilitare la traccia delle chiamate alla libreria di sistema specificando l'opzione -S per ltrace. Questa opzione è disabilitata/disattivata per impostazione predefinita poiché l'output diventerebbe un po' prolisso e si presume che le librerie di sistema siano generalmente molto più stabili e, in quanto tali, non debbano essere tracciate per iniziare. Diamo un'occhiata.

ltrace -fS tar -hcf –xz archive.tar.xz *

Oppure, a scopo di test:

ltrace -fS tar -hcf –xz archive.tar.xz * 2>&1 | head -n10 ltrace -fS tar -hcf –xz archivio.tar.xz * 2>&1 | coda -n10

Poiché l'output era consistente, abbiamo dovuto catturare la prima e l'ultima riga utilizzando un comando head and tail. Per poter utilizzare questi comandi abbiamo dovuto reindirizzare stderr a stdout utilizzando il reindirizzamento 2>&1 poiché ltrace riporterà per impostazione predefinita su stderr. Se sei interessato a saperne di più sul reindirizzamento, vedi Bash Automation and Scripting Basics (Parte 3).

Pubblicità

Ora che abbiamo aggiunto l'opzione -S, possiamo vedere tutte le librerie a cui si accede. Ad esempio, vediamo accedere a /etc/ld.so.preload. L'output è sequenziale (dall'alto verso il basso), quindi se ci sono altri eventi (sotto-elaborazione in fork, ecc.), questi verranno mostrati in linea nel momento in cui si verificano. Potremmo anche aggiungere l'opzione -t per l'output basato sul tempo:

Conclusioni

In questo articolo abbiamo introdotto e discusso il versatile programma ltrace, che è un ottimo strumento che consente di tracciare tutte le chiamate alla libreria dinamica un determinato programma fa. Abbiamo installato ltrace, configurato un ambiente di test ed eseguito alcuni comandi di ltrace con le opzioni più comunemente utilizzate.