Il comando strace
Il comando strace può essere utilizzato per intercettare e registrare le chiamate di sistema effettuate e i segnali ricevuti da un processo. Ciò consente di esaminare lo strato limite tra l'utente e lo spazio del kernel, che può essere molto utile per identificare il motivo per cui un processo non riesce.
L'uso di strace per analizzare come un programma interagisce con il sistema è particolarmente utile quando il codice sorgente non è immediatamente disponibile. Oltre alla sua importanza nella risoluzione dei problemi, strace può fornire una visione approfondita del funzionamento del sistema. Qualsiasi utente può tracciare i propri processi in esecuzione; inoltre, l'utente root può tracciare tutti i processi in esecuzione. Ad esempio, è possibile utilizzare quanto segue per collegarsi e tracciare il demone rsyslogd in esecuzione:
# strace -p $(pgrep rsyslogd) Process 819 attached select(1, NULL, NULL, NULL, {83009, 275934} ...
Traccia l'output
L'output di strace corrisponderà a una chiamata di sistema oa un segnale. L'output di una chiamata di sistema è composto da tre componenti:
1. La chiamata di sistema
2. Eventuali argomenti racchiusi tra parentesi
3. Il risultato della chiamata dopo il segno di uguale
Uno stato di uscita di -1 di solito indica un errore. Ad esempio:
# strace ls file1 execve("/bin/ls", ["ls", "file1"], [/* 21 vars */]) = 0 brk(0) = 0xadb000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f516bb79000 ..... close(1) = 0 munmap(0x7f516bb78000, 4096) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++
Le parentesi graffe vengono utilizzate per indicare le strutture C dereferenziate. Le parentesi quadre vengono utilizzate per indicare semplici puntatori o una matrice di valori.
Esempi di comando strace
Reindirizzamento della traccia a un file
Poiché strace crea spesso una grande quantità di output, è spesso conveniente reindirizzarlo a un file. Ad esempio, è possibile utilizzare quanto segue per avviare la shell bash, tracciare eventuali processi figlio biforcati e registrare tutti gli accessi ai file nel file files.trace:
# strace -f -o files.trace -e trace=file bash
Conteggio del numero di chiamate di sistema
Esegui il comando ls contando il numero di volte in cui è stata effettuata ciascuna chiamata di sistema e stampa i totali che mostrano il numero e il tempo trascorso in ciascuna chiamata (utile per la profilazione di base o l'isolamento dei colli di bottiglia):
# strace -c ls
Visualizzazione dei file aperti da un processo/daemon
L'esempio seguente mostra i tre file di configurazione che sshd di OpenSSH legge all'avvio. Nota che strace invia il suo output a STDERR per impostazione predefinita, quindi se vuoi reindirizzarlo ad altri comandi come grep per ulteriori modifiche devi reindirizzare l'output in modo appropriato:
# strace -f -eopen /usr/sbin/sshd 2>&1 | grep ssh
Tracciamento solo delle chiamate di sistema relative alla rete
Traccia solo le chiamate di sistema relative alla rete mentre Netcat tenta di connettersi a un servizio telnetd locale:
# strace -e trace=network nc localhost 23
Il comando ltrace
Il comando ltrace può essere utilizzato per intercettare e registrare le chiamate dinamiche effettuate alle librerie condivise. La quantità di output generata dal comando ltrace può essere schiacciante per alcuni comandi (soprattutto se l'opzione -S viene utilizzata per mostrare anche le chiamate di sistema). Puoi concentrare l'output solo sull'interazione tra il programma e un elenco di librerie. Ad esempio, per eseguire il comando id -Z e mostrare le chiamate effettuate al modulo libselinux.so, eseguire:
$ ltrace -l /lib/libselinux.so.1 id -Z is_selinux_enabled(0xc1c7a0, 0x9f291e8, 0xc1affc, 0, -1)a =1 getcon(0x804c2c8, 0xfee80ff4, 0x804b179, 0x804c020, 0)a =0 user_u:system_r:unconfined_t
Ricorda che puoi vedere a quali librerie è collegato un programma usando il comando ldd.