Saturday, November 6, 2010

UNIX: Fehler finden mit Strace

Oft reicht die Fehlersuche über Logmeldungen nicht aus, um einen Fehler zu beheben. Dann ist ein kontrolliertes Ausführen des Programms in einem Debugger erforderlich. Dafür sind debug-Symbole nötig, und meist ein Neubau erforderlich.

Ohne debug-Symbole können allerdings auch schon nützliche Informationen mit "strace" gewonnen werden. Das Programm zeigt alle "System Calls" einer Applikation auf. Meist ist dann im Fehlerfall schon zu erkennen, welche Datei geöffnet wird oder wo genau der Fehler tatsächlich entsteht.

Natürlich muss ein Daemon vorher im Vordergrund ausgeführt werden, um die strace Befehle zu sehen. Konkret habe ich das verwendet um PPTPd in Freetz zu debuggen, siehe Dokumentation im Freetz-Wiki.

Einfaches Beispiel der Strace-Verwendung:

# strace echo 3
execve("/bin/echo", ["echo", "3"], [/* 15 vars */]) = 0
brk(0)                                  = 0x1ec03000
uname({sys="Linux", node="unknown-namer", ...}) = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aeadb3aa000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=42988, ...}) = 0
mmap(NULL, 42988, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2aeadb3ac000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\355\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1432968, ...}) = 0
mmap(NULL, 3541032, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2aeadb5ac000
mprotect(0x2aeadb704000, 2093056, PROT_NONE) = 0
mmap(0x2aeadb903000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x157000) = 0x2aeadb903000
mmap(0x2aeadb908000, 18472, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2aeadb908000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aeadb90d000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aeadb90e000
arch_prctl(ARCH_SET_FS, 0x2aeadb90db20) = 0
open("/dev/urandom", O_RDONLY)          = 3
read(3, "(\333\372\211\343\357\201", 7) = 7
close(3)                                = 0
mprotect(0x2aeadb903000, 16384, PROT_READ) = 0
mprotect(0x2aeadb5a9000, 4096, PROT_READ) = 0
munmap(0x2aeadb3ac000, 42988)           = 0
brk(0)                                  = 0x1ec03000
brk(0x1ec24000)                         = 0x1ec24000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3927616, ...}) = 0
mmap(NULL, 3927616, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2aeadb90f000
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aeadbcce000
write(1, "3\n", 23
)                      = 2
close(1)                                = 0
munmap(0x2aeadbcce000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?

No comments:

Post a Comment