Der strace-Befehl
Der Befehl strace kann verwendet werden, um die getätigten Systemaufrufe und die von einem Prozess empfangenen Signale abzufangen und aufzuzeichnen. Dies ermöglicht die Untersuchung der Grenzschicht zwischen Benutzer- und Kernel-Space, was sehr nützlich sein kann, um zu identifizieren, warum ein Prozess fehlschlägt.
Die Verwendung von strace zur Analyse der Interaktion eines Programms mit dem System ist besonders nützlich, wenn der Quellcode nicht ohne Weiteres verfügbar ist.
Zusätzlich zu seiner Bedeutung bei der Fehlersuche kann strace einen tiefen Einblick in die Funktionsweise des Systems geben. Jeder Benutzer kann seine eigenen laufenden Prozesse verfolgen; Darüber hinaus kann der Root-Benutzer alle laufenden Prozesse verfolgen. Zum Beispiel könnte Folgendes verwendet werden, um an den laufenden rsyslogd-Daemon anzuhängen und ihn zu verfolgen:
# strace -p $(pgrep rsyslogd) Process 819 attached select(1, NULL, NULL, NULL, {83009, 275934} ...
strace-Ausgabe
Die Ausgabe von strace entspricht entweder einem Systemaufruf oder einem Signal. Die Ausgabe eines Systemaufrufs besteht aus drei Komponenten:
1. Der Systemaufruf
2. Alle in Klammern eingeschlossenen Argumente
3. Das Ergebnis des Aufrufs nach einem Gleichheitszeichen
Ein Exit-Status von -1 weist normalerweise auf einen Fehler hin. Zum Beispiel:
# 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 +++
Geschweifte Klammern werden verwendet, um dereferenzierte C-Strukturen anzuzeigen. Eckige Klammern werden verwendet, um einfache Zeiger oder ein Array von Werten anzugeben.
Beispiele für den Befehl strace
Trace in eine Datei umleiten
Da strace oft eine große Menge an Ausgaben erzeugt, ist es oft praktisch, sie in eine Datei umzuleiten. Beispielsweise könnte Folgendes verwendet werden, um die Bash-Shell zu starten, alle gegabelten untergeordneten Prozesse zu verfolgen und alle Dateizugriffe auf die Datei files.trace aufzuzeichnen:
# strace -f -o files.trace -e trace=file bash
Zählen der Systemaufrufe
Führen Sie den Befehl ls aus, zählen Sie, wie oft jeder Systemaufruf durchgeführt wurde, und geben Sie die Gesamtsummen aus, die die Anzahl und Zeit jedes Aufrufs anzeigen (nützlich für grundlegende Profilerstellung oder Engpassisolierung):
# strace -c ls
Anzeigen von Dateien, die von einem Prozess/Daemon geöffnet wurden
Das folgende Beispiel zeigt die drei Konfigurationsdateien, die OpenSSHs sshd beim Start liest. Beachten Sie, dass strace seine Ausgabe standardmäßig an STDERR sendet. Wenn Sie sie also zur weiteren Änderung an andere Befehle wie grep weiterleiten möchten, müssen Sie die Ausgabe entsprechend umleiten:
# strace -f -eopen /usr/sbin/sshd 2>&1 | grep ssh
Verfolgung nur netzwerkbezogener Systemaufrufe
Verfolgen Sie nur die netzwerkbezogenen Systemaufrufe, wenn Netcat versucht, sich mit einem lokalen telnetd-Dienst zu verbinden:
# strace -e trace=network nc localhost 23
Der ltrace-Befehl
Der Befehl ltrace kann verwendet werden, um die dynamischen Aufrufe an gemeinsam genutzte Bibliotheken abzufangen und aufzuzeichnen. Die Menge der vom ltrace-Befehl generierten Ausgabe kann für einige Befehle überwältigend sein (insbesondere wenn die Option -S verwendet wird, um auch Systemaufrufe anzuzeigen). Sie können die Ausgabe nur auf die Interaktion zwischen dem Programm und einer Liste von Bibliotheken konzentrieren. Um beispielsweise den Befehl id -Z auszuführen und die Aufrufe des Moduls libselinux.so anzuzeigen, führen Sie Folgendes aus:
$ 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
Denken Sie daran, dass Sie mit dem Befehl ldd sehen können, gegen welche Bibliotheken ein Programm gelinkt ist.