Linux で glib のソースコードを gdb で追ってみる
glib を使っているプログラムを実行するときに、デバッグ版の共有ライブラリをリンクすると、gdb で実行中のバイナリに対応するソースコードを追うことができる。
まず、インストールされている glib のバージョンを調べる。
$ pkg-config --modversion glib-2.0 2.14.1
このバージョンの glib をダウンロードして展開して configure する。CFLAGS="-g" を指定しないと、CFLAGS に -O2 オプションがついてしまいバイナリが最適化コンパイルされてしまうようだ。そうするとデバッグ時にバイナリとソースコードが対応しなくて困ることになる (実は最初この問題ではまったorz) 。
$ wget http://ftp.gnome.org/pub/gnome/sources/glib/2.14/glib-2.14.1.tar.bz2 $ tar jxf glib-2.14.1.tar.bz2 $ cd glib-2.14.1 $ ./configure CFLAGS="-g"
make する。(make install は不要)
$ make
ここまでの操作で、./glib/.libs の中に libglib-2.0.so ができているはず。これがデバッグ版の glib となる。
この後、プログラムを実行するとき環境変数 LD_LIBRARY_PATH にこのデバッグ版の glib のパスを指定すると、gdb でソースコードを追うことができるようになる。こんな感じ。
$ LD_LIBRARY_PATH=/home/.../glib-2.14.1/glib/.libs/ gdb ./sample GNU gdb 6.6-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu"... Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (gdb) run Starting program: /home/.../sample ^C Program received signal SIGINT, Interrupt. 0xffffe410 in __kernel_vsyscall () (gdb) i s #0 0xffffe410 in __kernel_vsyscall () #1 0xb7dbd5ab in poll () from /lib/tls/i686/cmov/libc.so.6 #2 0xb7e855f3 in g_main_context_poll (context=0x804a008, timeout=1000, priority=2147483647, fds=0x0, n_fds=0) at gmain.c:2996 #3 0xb7e849ba in g_main_context_iterate (context=0x804a008, block=1, dispatch=1, self=0x804ae98) at gmain.c:2689 #4 0xb7e851c5 in IA__g_main_loop_run (loop=0x804ae88) at gmain.c:2898 #5 0x080484ea in main () at example2.c:22 (gdb) up 2 #2 0xb7e855f3 in g_main_context_poll (context=0x804a008, timeout=1000, priority=2147483647, fds=0x0, n_fds=0) at gmain.c:2996 2996 if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR) (gdb) list 2991 LOCK_CONTEXT (context); 2992 2993 poll_func = context->poll_func; 2994 2995 UNLOCK_CONTEXT (context); 2996 if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR) 2997 { 2998 #ifndef G_OS_WIN32 2999 g_warning ("poll(2) failed due to: %s.", 3000 g_strerror (errno)); (gdb)