Wie soll Strace verwendet werden?

273

Ein Kollege sagte mir einmal, dass die letzte Option, wenn unter Linux nicht alles debuggt , die Verwendung von strace war .

Ich habe versucht, die Wissenschaft hinter diesem seltsamen Tool zu lernen, aber ich bin kein Systemadministrator und habe keine wirklichen Ergebnisse erzielt.

So,

  • Was ist es genau und was macht es?
  • Wie und in welchen Fällen sollte es verwendet werden?
  • Wie soll die Ausgabe verstanden und verarbeitet werden?

Kurz gesagt , in einfachen Worten , wie funktioniert dieses Zeug?

e-satis
quelle
2
strace -p <pid> wird Ihnen sagen, was gerade mit Ihrem Programm los ist ..... schnell und einfach als GDB
ernesto
1
Ich persönlich finde es man stracesehr einfach zu lesen und nützlich. (PS wusste bis gestern nichts über strace und kein Linux-Experte)
Alexander Malakhov
1
"strace is a system call tracer" - es zeigt Ihnen nur, welche Kernelfunktionen (mit ihren Argumenten) als Ergebnis Ihres Programms aufgerufen werden.
Pithikos

Antworten:

184

Strace Übersicht
strace kann als leichter Debugger angesehen werden. Dadurch kann ein Programmierer / Benutzer schnell herausfinden, wie ein Programm mit dem Betriebssystem interagiert. Dies geschieht durch Überwachung von Systemaufrufen und -signalen.

Verwendet
gut, wenn Sie keinen Quellcode haben oder sich nicht die Mühe machen möchten, ihn wirklich durchzugehen.
Auch nützlich für Ihren eigenen Code, wenn Sie keine Lust haben, GDB zu öffnen, sondern nur daran interessiert sind, die externe Interaktion zu verstehen.

Eine gute kleine Einführung
Ich bin neulich auf dieses Intro gestoßen, um Strace Use zu verwenden: Strace Hello World

John Mulder
quelle
Was ist, wenn Sie etwas unter der Ebene verwenden, das die Überwachung überwacht?
Pacerier
In diesem Fall @Pacerier check ltrace stackoverflow.com/a/52012215/5884955
prosti
Es eignet sich hervorragend zum Debuggen von Programmen auf niedriger Ebene, die nur / meistens existieren, um interessante Systemaufrufe durchzuführen, oder um mit neuen Optionen für Systemaufrufe zu experimentieren, um zu sehen, was Ihr Betriebssystem tut. Dies erspart im Grunde das Schreiben von Protokollierungs- / Fehlerprüfungscode für einmalige Experimente. (Oder wenn Sie in asm schreiben oder etwas, bei dem die Wahrscheinlichkeit groß ist, dass Sie versehentlich die falschen Argumente oder sogar die falsche Rufnummer übergeben haben.) Strace ist viel schneller als GDB, da es nach errno-Codes für Sie sucht, z. B. -EFAULT(oops, schreibgeschützt) buffer) oder -ENOENT(oops, lief aus dem falschen Verzeichnis, in dem der relative Pfad nicht funktioniert hat).)
Peter Cordes
62

In einfachen Worten verfolgt strace alle von einem Programm ausgegebenen Systemaufrufe zusammen mit ihren Rückkehrcodes. Denken Sie an Dinge wie Datei- / Socket-Operationen und viel dunkelere.

Dies ist am nützlichsten, wenn Sie über Kenntnisse in C verfügen, da hier Systemaufrufe genauer für Standardaufrufe der C-Bibliothek stehen würden.

Angenommen, Ihr Programm lautet / usr / local / bin / Husten. Verwenden Sie einfach:

strace /usr/local/bin/cough <any required argument for cough here>

oder

strace -o <out_file> /usr/local/bin/cough <any required argument for cough here>

in 'out_file' schreiben.

Alle Strace-Ausgaben werden an stderr gesendet (Vorsicht, das schiere Volumen erfordert häufig eine Umleitung in eine Datei). In den einfachsten Fällen wird Ihr Programm mit einem Fehler abgebrochen und Sie können sehen, wo die letzten Interaktionen mit dem Betriebssystem in der Strace-Ausgabe stattgefunden haben.

Weitere Informationen sollten verfügbar sein mit:

man strace
bltxd
quelle
36

strace listet alle Systemaufrufe auf , die von dem Prozess ausgeführt werden, auf den es angewendet wird. Wenn Sie nicht wissen, was Systemaufrufe bedeuten, können Sie nicht viel Kilometer damit sammeln.

Wenn Ihr Problem jedoch Dateien oder Pfade oder Umgebungswerte umfasst, können Sie durch Ausführen von strace auf dem problematischen Programm und Umleiten der Ausgabe in eine Datei und anschließendes Durchsuchen dieser Datei nach Ihrer Pfad- / Datei- / Umgebungszeichenfolge erkennen, was Ihr Programm tatsächlich versucht tun, im Unterschied zu dem, was Sie erwartet haben.

Asaf Bartov
quelle
7
Und für nicht triviale Programme ist dies oft wie das Trinken aus einem Feuerwehrschlauch, so dass Sie Ihre Arbeit für Sie durchgeschnitten haben, um die Ergebnisse
durchzugehen
17
strace <prog_name>ein Programm verfolgen. strace -o <out_file> <prog_name>in eine Datei zu legen
Jestin Joy
8
strace prog 2> & 1 | grep ^ open \ (
Eisbaw
10
Oder einfach: strace -e open myprogODER für alle dateibezogenen Systemaufrufe:strace -e file myprog
Amit Naidu
17

Strace ist ein hervorragendes Tool zur Untersuchung von Produktionssystemen, bei denen Sie es sich nicht leisten können, diese Programme unter einem Debugger auszuführen. Insbesondere haben wir strace in den folgenden zwei Situationen verwendet:

  • Das Programm foo scheint festgefahren zu sein und reagiert nicht mehr. Dies könnte ein Ziel für gdb sein; Wir hatten jedoch nicht immer den Quellcode oder hatten es manchmal mit Skriptsprachen zu tun, die nicht einfach unter einem Debugger ausgeführt werden konnten. In diesem Fall führen Sie strace für ein bereits ausgeführtes Programm aus und erhalten eine Liste der ausgeführten Systemaufrufe. Dies ist besonders nützlich, wenn Sie eine Client / Server-Anwendung oder eine Anwendung untersuchen, die mit einer Datenbank interagiert
  • Untersuchen, warum ein Programm langsam ist. Insbesondere waren wir gerade auf ein neues verteiltes Dateisystem umgestiegen und der neue Durchsatz des Systems war sehr langsam. Sie können strace mit der Option '-T' angeben, die angibt, wie viel Zeit in jedem Systemaufruf verbracht wurde. Dies half festzustellen, warum das Dateisystem die Dinge verlangsamte.

Ein Beispiel für die Analyse mit strace finden Sie in meiner Antwort auf diese Frage .

terson
quelle
15

Ich benutze strace die ganze Zeit, um Berechtigungsprobleme zu debuggen. Die Technik geht so:

$ strace -e trace=open,stat,read,write gnome-calculator

Wo gnome-calculatorist der Befehl, den Sie ausführen möchten?

Jeff Sheffield
quelle
8

strace -tfp PID überwacht die Systemaufrufe des PID-Prozesses, sodass wir unseren Prozess- / Programmstatus debuggen / überwachen können.

Leslie Zhu
quelle
6

Strace kann als Debugging-Tool oder als primitiver Profiler verwendet werden.

Als Debugger können Sie sehen, wie bestimmte Systemaufrufe aufgerufen, ausgeführt und zurückgegeben wurden. Dies ist sehr wichtig, da Sie nicht nur sehen können, dass ein Programm fehlgeschlagen ist, sondern auch, WARUM ein Programm fehlgeschlagen ist. Normalerweise ist es nur ein Ergebnis einer miesen Codierung, die nicht alle möglichen Ergebnisse eines Programms erfasst. In anderen Fällen handelt es sich nur um fest codierte Pfade zu Dateien. Ohne Anstrengung kann man erraten, was wo und wie schief gelaufen ist. Mit strace erhalten Sie eine Aufschlüsselung eines Systemaufrufs. In der Regel sagt Ihnen schon ein Blick auf einen Rückgabewert viel.

Profiling ist eine andere Verwendung. Sie können damit die Ausführung jedes Systemaufrufs einzeln oder als Aggregat zeitlich festlegen. Dies reicht möglicherweise nicht aus, um Ihre Probleme zu beheben, wird jedoch die Liste der potenziellen Verdächtigen zumindest erheblich einschränken. Wenn in einer einzelnen Datei viele Fopen / Close-Paare angezeigt werden, öffnen und schließen Sie Dateien bei jeder Ausführung einer Schleife möglicherweise unnötig, anstatt sie außerhalb einer Schleife zu öffnen und zu schließen.

Ltrace ist Straces enger Cousin, auch sehr nützlich. Sie müssen lernen, zu unterscheiden, wo Ihr Engpass liegt. Wenn eine Gesamtausführung 8 Sekunden beträgt und Sie nur 0,05 Sekunden für Systemaufrufe aufwenden, hilft es Ihnen nicht viel, das Programm zu belasten. Das Problem liegt in Ihrem Code, der normalerweise ein logisches Problem ist, oder das Programm benötigt es tatsächlich so lange zu laufen.

Das größte Problem bei strace / ltrace ist das Lesen ihrer Ausgabe. Wenn Sie nicht wissen, wie die Anrufe getätigt werden oder zumindest die Namen der Systemaufrufe / Funktionen, wird es schwierig sein, die Bedeutung zu entschlüsseln. Zu wissen, was die Funktionen zurückgeben, kann auch sehr nützlich sein, insbesondere für verschiedene Fehlercodes. Während es ein Schmerz ist, zu entziffern, geben sie manchmal wirklich eine Perle des Wissens zurück; Als ich eine Situation sah, in der mir die Inodes ausgegangen waren, aber nicht der freie Speicherplatz, gaben mir alle üblichen Dienstprogramme keine Warnung, ich konnte einfach keine neue Datei erstellen. Das Lesen des Fehlercodes aus der Ausgabe von strace zeigte mir die richtige Richtung.

Marcin
quelle
4

Strace ist ein Tool, mit dem Sie erfahren, wie Ihre Anwendung mit Ihrem Betriebssystem interagiert.

Dazu erfahren Sie, welches Betriebssystem Ihre Anwendung verwendet und mit welchen Parametern sie aufgerufen wird.

So sehen Sie beispielsweise, welche Dateien Ihr Programm zu öffnen versucht, und ob der Aufruf erfolgreich ist.

Mit diesem Tool können Sie alle möglichen Probleme beheben. Wenn die Anwendung beispielsweise angibt, dass sie keine Bibliothek finden kann, von der Sie wissen, dass Sie sie installiert haben, teilt Ihnen strace mit, wo die Anwendung nach dieser Datei sucht.

Und das ist nur eine Spitze des Eisbergs.

Luka Marinko
quelle
das ist sehr genau.
Prosti
4

strace ist ein gutes Werkzeug, um zu lernen, wie Ihr Programm verschiedene Systemaufrufe (Anforderungen an den Kernel) ausführt, und meldet auch diejenigen, die fehlgeschlagen sind, zusammen mit dem mit diesem Fehler verbundenen Fehlerwert. Nicht alle Fehler sind Fehler. Beispielsweise kann ein Code, der versucht, nach einer Datei zu suchen, einen ENOENT-Fehler (keine solche Datei oder kein solches Verzeichnis) erhalten, dies kann jedoch ein akzeptables Szenario in der Logik des Codes sein.

Ein guter Anwendungsfall für die Verwendung von strace ist das Debuggen von Race-Bedingungen während der temporären Dateierstellung. Beispielsweise kann ein Programm, das möglicherweise Dateien durch Anhängen der Prozess-ID (PID) an eine vorher festgelegte Zeichenfolge erstellt, in Multithread-Szenarien auf Probleme stoßen. [Eine PID + TID (Prozess-ID + Thread-ID) oder ein besserer Systemaufruf wie mkstemp beheben dies].

Es ist auch gut zum Debuggen von Abstürzen. Sie können diesen (meinen) Artikel über Strace- und Debugging-Abstürze nützlich finden.

Mohit
quelle
4

Minimal lauffähiges Beispiel

Wenn ein Konzept nicht klar ist, gibt es ein einfacheres Beispiel, das Sie nicht gesehen haben und das es erklärt.

In diesem Fall ist dieses Beispiel die freistehende (keine libc) Hallo-Welt der Linux x86_64-Assembly:

hallo.S

.text
.global _start
_start:
    /* write */
    mov $1, %rax    /* syscall number */
    mov $1, %rdi    /* stdout */
    mov $msg, %rsi  /* buffer */
    mov $len, %rdx  /* buffer len */
    syscall

    /* exit */
    mov $60, %rax   /* exit status */
    mov $0, %rdi    /* syscall number */
    syscall
msg:
    .ascii "hello\n"
len = . - msg

GitHub stromaufwärts .

Zusammenbauen und ausführen:

as -o hello.o hello.S
ld -o hello.out hello.o
./hello.out

Gibt das erwartete aus:

hello

Verwenden wir nun Strace für dieses Beispiel:

env -i ASDF=qwer strace -o strace.log -s999 -v ./hello.out arg0 arg1
cat strace.log

Wir gebrauchen:

strace.log enthält jetzt:

execve("./hello.out", ["./hello.out", "arg0", "arg1"], ["ASDF=qwer"]) = 0
write(1, "hello\n", 6)                  = 6
exit(0)                                 = ?
+++ exited with 0 +++

Bei einem so minimalen Beispiel ist jedes einzelne Zeichen der Ausgabe selbstverständlich:

  • execveZeile: Zeigt an, wie sie straceausgeführt wird hello.out, einschließlich der CLI-Argumente und der Umgebung, wie unter dokumentiertman execve

  • writeZeile: Zeigt den Schreibsystemaufruf an, den wir durchgeführt haben. 6ist die Länge der Zeichenfolge "hello\n".

    = 6ist der Rückgabewert des Systemaufrufs, der, wie in dokumentiert, man 2 writedie Anzahl der geschriebenen Bytes ist.

  • exitZeile: Zeigt den von uns getätigten Aufruf des Exit-Systems an. Es gibt keinen Rückgabewert, da das Programm beendet wurde!

Komplexere Beispiele

Die Anwendung von strace dient natürlich dazu, festzustellen, welche Systemaufrufe komplexe Programme tatsächlich ausführen, um das Debuggen / Optimieren Ihres Programms zu unterstützen.

Insbesondere haben die meisten Systemaufrufe, die unter Linux wahrscheinlich auftreten, Glibc-Wrapper, viele davon von POSIX .

Intern verwenden die glibc-Wrapper die Inline-Assembly mehr oder weniger folgendermaßen: Wie rufe ich einen Systemaufruf über sysenter in der Inline-Assembly auf?

Das nächste Beispiel, das Sie studieren sollten, ist eine POSIX- writeHallo-Welt:

Haupt c

#define _XOPEN_SOURCE 700
#include <unistd.h>

int main(void) {
    char *msg = "hello\n";
    write(1, msg, 6);
    return 0;
}

Kompilieren und ausführen:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

Dieses Mal werden Sie sehen, dass eine Reihe von Systemaufrufen von glibc ausgeführt werden, bevor maineine schöne Umgebung für main eingerichtet wird.

Dies liegt daran, dass wir jetzt kein freistehendes Programm verwenden, sondern ein allgemeineres glibc-Programm, das libc-Funktionen ermöglicht.

Dann strace.logenthält an jedem Ende :

write(1, "hello\n", 6)                  = 6
exit_group(0)                           = ?
+++ exited with 0 +++

Wir schließen daraus, dass die writePOSIX-Funktion überraschenderweise den Linux write-Systemaufruf verwendet.

Wir beobachten auch, dass dies return 0zu einem exit_groupAnruf statt führt exit. Ha, ich wusste nichts davon! Deshalb straceist es so cool. man exit_groupdann erklärt:

Dieser Systemaufruf entspricht exit (2), außer dass nicht nur der aufrufende Thread, sondern alle Threads in der Thread-Gruppe des aufrufenden Prozesses beendet werden.

Und hier ist ein weiteres Beispiel, in dem ich untersucht habe, welche Systemaufrufe dlopenverwendet werden: /unix/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710

Getestet in Ubuntu 16.04, GCC 6.4.0, Linux Kernel 4.4.0.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
2

Hier sind einige Beispiele, wie ich mit strace in Websites grabe. Hoffe das ist hilfreich.

Überprüfen Sie die Zeit bis zum ersten Byte wie folgt:

time php index.php > timeTrace.txt

Sehen Sie, wie viel Prozent der Aktionen was tun. Viele lstatund fstatkönnten ein Hinweis darauf sein, dass es Zeit ist, den Cache zu leeren:

strace -s 200 -c php index.php > traceLstat.txt

Gibt a aus, trace.txtdamit Sie genau sehen können, welche Anrufe getätigt werden.

strace -Tt -o Fulltrace.txt php index.php

Verwenden Sie diese auf prüfen , ob irgendetwas zwischen nahm .1zu .9einer Sekunde Last:

cat Fulltrace.txt | grep "[<]0.[1-9]" > traceSlowest.txt

Sehen Sie, welche fehlenden Dateien oder Verzeichnisse in der strace. Dies wird eine Menge Dinge ausgeben, die unser System betreffen - die einzigen relevanten Bits betreffen die Dateien des Kunden:

strace -vv php index.php 2>&1 | sed -n '/= -1/p' > traceFailures.txt
Kerwin Smith
quelle
1

Ich mochte einige der Antworten, in denen straceüberprüft wird, wie Sie mit Ihrem Betriebssystem interagieren.

Genau das können wir sehen. Das System ruft auf. Wenn Sie vergleichen straceund ltraceder Unterschied ist offensichtlicher.

$>strace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         7           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0        11           close
  0.00    0.000000           0        10           fstat
  0.00    0.000000           0        17           mmap
  0.00    0.000000           0        12           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         8         8 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2           getdents
  0.00    0.000000           0         2         2 statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         9           openat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    93        10 total

Auf der anderen Seite gibt es, ltracedass Funktionen verfolgt.

$>ltrace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls      function
------ ----------- ----------- --------- --------------------
 15.52    0.004946         329        15 memcpy
 13.34    0.004249          94        45 __ctype_get_mb_cur_max
 12.87    0.004099        2049         2 fclose
 12.12    0.003861          83        46 strlen
 10.96    0.003491         109        32 __errno_location
 10.37    0.003303         117        28 readdir
  8.41    0.002679         133        20 strcoll
  5.62    0.001791         111        16 __overflow
  3.24    0.001032         114         9 fwrite_unlocked
  1.26    0.000400         100         4 __freading
  1.17    0.000372          41         9 getenv
  0.70    0.000222         111         2 fflush
  0.67    0.000214         107         2 __fpending
  0.64    0.000203         101         2 fileno
  0.62    0.000196         196         1 closedir
  0.43    0.000138         138         1 setlocale
  0.36    0.000114         114         1 _setjmp
  0.31    0.000098          98         1 realloc
  0.25    0.000080          80         1 bindtextdomain
  0.21    0.000068          68         1 opendir
  0.19    0.000062          62         1 strrchr
  0.18    0.000056          56         1 isatty
  0.16    0.000051          51         1 ioctl
  0.15    0.000047          47         1 getopt_long
  0.14    0.000045          45         1 textdomain
  0.13    0.000042          42         1 __cxa_atexit
------ ----------- ----------- --------- --------------------
100.00    0.031859                   244 total

Obwohl ich die Handbücher mehrmals überprüft habe, habe ich den Ursprung des Namens nicht gefunden, straceaber es handelt sich wahrscheinlich um eine Systemaufrufverfolgung, da dies offensichtlich ist.

Es gibt drei größere Notizen zu sagen strace.

Hinweis 1: Beide Funktionen straceund ltraceverwenden den Systemaufruf ptrace. So ptraceSystemaufruf ist effektiv , wie stracefunktioniert.

Der Systemaufruf ptrace () bietet ein Mittel, mit dem ein Prozess (der "Tracer") die Ausführung eines anderen Prozesses (der "Tracee") beobachten und steuern sowie den Speicher und die Register des Tracees untersuchen und ändern kann. Es wird hauptsächlich zum Implementieren von Breakpoint-Debugging und Systemaufrufverfolgung verwendet.

Hinweis 2: Es gibt verschiedene Parameter, mit denen Sie arbeiten können strace, da stracediese sehr ausführlich sein können. Ich experimentiere gerne damit, -cwas wie eine Zusammenfassung der Dinge ist. Basierend auf -ckönnen Sie einen Systemaufruf auswählen, -e trace=openbei dem nur dieser Aufruf angezeigt wird. Dies kann interessant sein, wenn Sie untersuchen, welche Dateien während des von Ihnen verfolgten Befehls geöffnet werden. Und natürlich können Sie das grepfür den gleichen Zweck verwenden, aber beachten Sie, dass Sie wie 2>&1 | grep etcfolgt umleiten müssen, um zu verstehen, dass auf Konfigurationsdateien verwiesen wird, als der Befehl ausgegeben wurde.

Anmerkung 3: Ich finde diese sehr wichtige Anmerkung. Sie sind nicht auf eine bestimmte Architektur beschränkt. stracewird Sie umhauen, da es über Binärdateien verschiedener Architekturen verfolgen kann. Geben Sie hier die Bildbeschreibung ein

Prosti
quelle