-dbg パッケージでライブラリのシンボル情報を得る

たとえば libc6 だったら libc6-dbg というのがデバッグ用シンボル情報のパッケージです(Debian 系の場合)。

$ sudo apt-get install libc6-dbg

$ sudo apt-get install samba-dbg

なにがうれしいか,というと元ソースコードの行とか引数の状況とか gdb で得ることができます。

先ほどのデバッグです。

$ gdb test

GNU gdb 6.8-debian
...... snip snip snip ......
This GDB was configured as "i486-linux-gnu"...

デバッグシンボルパッケージは /usr/lib/debug 以下にインストールされるので,こちらを優先して読み込むように LD_LIBRARY_PATH 環境変数で指定してあげます。

(gdb) set environment LD_LIBRARY_PATH=/usr/lib/debug

んで,デバッグ開始。

(gdb) start SMB_SERVER_NAME

Breakpoint 1 at 0x80484d5: file test.c, line 25.
Starting program: /home/dayflower/test SMB_SERVER_NAME
[Thread debugging using libthread_db enabled]
[New Thread 0xb79bf6d0 (LWP 8302)]
[Switching to Thread 0xb79bf6d0 (LWP 8302)]
main (argc=2, argv=0xbfc53574) at test.c:25
25	    hp = gethostbyname(argv[1]);

(gdb) cont
Continuing.
*** glibc detected *** /home/dayflower/test: realloc(): invalid pointer: 0xb7fb806c ***
======= Backtrace: =========
/usr/lib/debug/libc.so.6[0xb7cd7c37]
/usr/lib/debug/libc.so.6(realloc+0x267)[0xb7cdba87]
/usr/lib/debug/libc.so.6(realloc+0x42)[0xb7cdb862]

...... snip snip snip ......

Program received signal SIGABRT, Aborted.
0xb7c9a1b6 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
	in ../nptl/sysdeps/unix/sysv/linux/raise.c

コマンドラインと同じように abort しました。

あんまり詳しい情報がないのは,この backtrace は libc がおまけで出してくれただけだからです。gdb から backtrace を見てみます。

(gdb) bt

#0  0xb7c9a1b6 in *__GI_raise (sig=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0xb7c9ba31 in *__GI_abort () at abort.c:88
#2  0xb7cd1fdb in __libc_message (do_abort=2, 
    fmt=0xb7d8a4e8 "*** glibc detected *** %s: %s: 0x%s ***\n")
    at ../sysdeps/unix/sysv/linux/libc_fatal.c:170
#3  0xb7cd7c37 in malloc_printerr (action=2, 
    str=0xb7d87454 "realloc(): invalid pointer", ptr=<value optimized out>)
    at malloc.c:5891
#4  0xb7cdba87 in *__GI___libc_realloc (oldmem=0x0, bytes=4) at malloc.c:3666
#5  0xb7cdb862 in *__GI___libc_realloc (oldmem=0xb7fb806c, bytes=4)
    at malloc.c:3647
#6  0xb7947e9b in Realloc (p=0xb7fb806c, size=4, free_old_on_error=1)
    at lib/util.c:1065
#7  0xb7947f83 in realloc_array (p=0xb7fb806c, el_size=4, count=8302, 
    free_old_on_error=1) at lib/util.c:1091
#8  0xb7930499 in debug_add_class (classname=0xb797a6f9 "all")
    at lib/debug.c:320
#9  0xb7930628 in debug_init () at lib/debug.c:546
#10 0xb7930662 in setup_logging (pname=0xb796cf60 "nss_wins", interactive=0)
    at lib/debug.c:556
#11 0xb78db7f2 in _nss_wins_gethostbyname_r (hostname=0xbfc54a9c "SMB_SERVER_NAME", 
    he=0xb7da7ae4, buffer=0x804a028 "&#65533;\002", buflen=1024, h_errnop=0xb79bf6ac)
    at nsswitch/wins.c:87
#12 0xb7d4adcb in __gethostbyname_r (name=0xbfc54a9c "SMB_SERVER_NAME", 
    resbuf=0xb7da7ae4, buffer=0x804a028 "&#65533;\002", buflen=1024, 
    result=0xbfc53498, h_errnop=0xbfc53494) at ../nss/getXXbyYY_r.c:226
#13 0xb7d4a638 in gethostbyname (name=0xbfc54a9c "SMB_SERVER_NAME")
    at ../nss/getXXbyYY.c:116
#14 0x080484e5 in main (argc=Cannot access memory at address 0x206e
) at test.c:25

このようにソースファイル名と行数と引数の情報がわかります。デバッグ用ライブラリじゃないとここまでわかりません。

ソースファイルのパスを指定するともっと便利にデバッグできるはず。やり方がわからないけど。