13.1 Fehlersuche

13.1.1 Angeben der benötigten Bibliothek: ldd

Mit dem Kommando ldd können Sie ermitteln, welche Bibliotheken die als Argument angegebene dynamische Programmdatei laden würde.

tux@mercury:~> ldd /bin/ls
	linux-vdso.so.1 =>  (0x00007fff1ddff000)
	librt.so.1 => /lib64/librt.so.1 (0x00007f1315993000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f1315776000)
	libacl.so.1 => /lib64/libacl.so.1 (0x00007f131556e000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f1315215000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f1314ff9000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f1315b9c000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f1314df5000)
	libattr.so.1 => /lib64/libattr.so.1 (0x00007f1314bf0000)

Statische Binärdateien benötigen keine dynamischen Bibliotheken.

tux@mercury:~> ldd /sbin/ldconfig
        not a dynamic executable
tux@mercury:~> file /bin/sash
/sbin/ldconfig: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for \
 GNU/Linux 2.6.4, statically linked, stripped

13.1.2 Bibliotheksaufrufe eines aktiven Programms: ltrace

Mit dem Befehl ltrace können Sie die Bibliotheksaufrufe eines Prozesses verfolgen. Dieser Befehl wird auf ähnliche Weise verwendet wie strace. Der Parameter -c gibt die Anzahl und die Dauer der erfolgten Bibliotheksaufrufe aus:

tux@mercury:~> ltrace -c find ~
    seconds  usecs/call     calls      function
------ ----------- ----------- --------- --------------------
 57.49   40.170338        1580     25411 __fprintf_chk
 11.50    8.036963         237     33894 readdir
  7.18    5.019464          98     50822 __ctype_get_mb_cur_max
  6.02    4.206130         767      5480 fchdir
  3.30    2.304577         209     11022 malloc
  3.18    2.224551         406      5479 __open_2
[...]
  0.00    0.000025          25         1 __cxa_atexit
------ ----------- ----------- --------- --------------------
100.00   69.878004                363666 total

13.1.3 Systemaufrufe eines aktiven Programms: strace

Mit dem Dienstprogramm strace können Sie alle Systemaufrufe eines aktuell ausgeführten Prozesses verfolgen. Jede Ausgabezeile des Kommandos enthält den Systemaufrufnamen, gefolgt von seinen Argumenten in Klammern und seinem Rückgabewert. Geben Sie den Befehl wie üblich ein und fügen Sie am Zeilenanfang strace hinzu:

tux@mercury:~> strace ls
execve("/bin/ls", ["ls"], [/* 52 vars */]) = 0
brk(0)                                  = 0x618000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) \
	= 0x7f9848667000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) \
	= 0x7f9848666000
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=200411, ...}) = 0
mmap(NULL, 200411, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9848635000
close(3)                                = 0
open("/lib64/librt.so.1", O_RDONLY)     = 3
[...]
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) \
	= 0x7f9848508000
write(1, "bin\nDesktop\nDocuments\n", 22bin
Desktop
Documents
) = 22
close(1)                                = 0
munmap(0x7f9848508000, 4096)            = 0
close(2)                                = 0
exit_group(0)

Um beispielsweise alle Versuche, eine bestimmte Datei zu öffnen, zu verfolgen, geben Sie Folgendes ein:

tux@mercury:~> strace -e open ls .bashrc
open("/etc/ld.so.cache", O_RDONLY)       = 3
open("/lib64/librt.so.1", O_RDONLY)      = 3
open("/lib64/libselinux.so.1", O_RDONLY) = 3
open("/lib64/libacl.so.1", O_RDONLY)     = 3
open("/lib64/libc.so.6", O_RDONLY)       = 3
open("/lib64/libpthread.so.0", O_RDONLY) = 3
[...]

Um alle untergeordneten Prozesse zu verfolgen, verwenden Sie den Parameter -f. Das Verhalten und das Ausgabeformat von strace können weitgehend gesteuert werden. Weitere Informationen erhalten Sie durch die Eingabe von man strace.