ちょこっとGDB

gdbを使って、起動済みプロセスのデバッグを行う

$ gdb
GNU gdb Red Hat Linux (6.5-37.el5_2.2rh)
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 "i386-redhat-linux-gnu".
(gdb) dir GUI/bin/cgisessiond/ <==== 参照するソースのパスを登録 Tab補完できる
Source directories searched: /home/crk/hogehoge/GUI/bin/cgisessiond:$cdir:$cwd
(gdb) dir GUI/cgi/partition/remote_kvms_cr_setup/
Source directories searched: /home/crk/hogehoge/GUI/cgi/partition/remote_kvms_cr_setup:/home/crk/hogehoge/GUI/bin/cgisessiond:$cdir:$cwd
(gdb) dir lib/Setup/bin/
Source directories searched: /home/crk/hogehoge/lib/Setup/bin:/home/crk/hogehoge/GUI/cgi/partition/remote_kvms_cr_setup:/home/crk/hogehoge/GUI/bin/cgisessiond:$cdir:$cwd
(gdb) attach 20116 <==== デバッグするプロセスIDをattach
Attaching to process 20116
Reading symbols from /home/crk/hogehoge/GUI/bin/cgisessiond/cgisessiond...done.
Using host libthread_db library "/lib/libthread_db.so.1".
Reading symbols from /home/crk/hogehoge/lib/libdummy_ipmiclient.so.1...done.
Loaded symbols for /home/crk/hogehoge/lib/libdummy_ipmiclient.so.1
Reading symbols from /lib/libpam.so.0...done.
Loaded symbols for /lib/libpam.so.0
Reading symbols from /home/crk/hogehoge/lib/libschedule.so.1...done.
Loaded symbols for /home/crk/hogehoge/lib/libschedule.so.1
Reading symbols from /lib/libpthread.so.0...done.
[Thread debugging using libthread_db enabled]
[New Thread -1208051296 (LWP 20116)]
[New Thread 129751952 (LWP 20143)]
[New Thread 79842192 (LWP 20136)]
[New Thread 104491920 (LWP 20124)]
[New Thread 69352336 (LWP 20121)]
[New Thread 47803280 (LWP 20120)]
[New Thread 37313424 (LWP 20119)]
[New Thread 58862480 (LWP 20118)]
[New Thread 26823568 (LWP 20117)]
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /home/crk/hogehoge/lib/libmmbcommon.so.1...done.
Loaded symbols for /home/crk/hogehoge/lib/libmmbcommon.so.1
   :
Reading symbols from /lib/librt.so.1...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /lib/libnsl.so.1...done.
Loaded symbols for /lib/libnsl.so.1
0x0084d402 in __kernel_vsyscall ()
(gdb) b RemoteKVMSCRSetupPage.cpp:382 <==== RemoteKVMSCRSetupPage.cppの382行目にブレークポイント設定
No source file named RemoteKVMSCRSetupPage.cpp. <==== でもこれってCGI側だから、このプロセスでは参照不可なのさ
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (RemoteKVMSCRSetupPage.cpp:382) pending.
(gdb) b TrSetRemoteKVMSConfigData.cpp:41 <==== TrSetRemoteKVMSConfigData.cppの41行目にブレークポイント設定
Breakpoint 2 at 0x80d742f: file TrSetRemoteKVMSConfigData.cpp, line 41.
(gdb) i b <==== ブレークポイントの一覧
Num Type Disp Enb Address What
1 breakpoint keep y RemoteKVMSCRSetupPage.cpp:382
2 breakpoint keep y 0x080d742f in TrSetRemoteKVMSConfigData::execute() at TrSetRemoteKVMSConfigData.cpp:41
(gdb) del 1 <==== ブレークポイントの削除
(gdb) c <==== continueの指示
Continuing.
Breakpoint 2, TrSetRemoteKVMSConfigData::execute (this=0xb7c00468) at TrSetRemoteKVMSConfigData.cpp:42
42 if (!recieveData(&rcvInfo)) {
(gdb) next <==== 次の行へ。以降はリターンすると直前のコマンドの繰り返し
49 PrimitiveTypeWrapper() {}
(gdb) <==== なのでここはリターンのみ
53 if (!packet.setSerialized(rcvInfo, getReqDataLength())) {
(gdb)
135 if (size > sizeof(PRIMITIVE_TYPE)) {
(gdb)
138 memcpy(&data, inData, sizeof(PRIMITIVE_TYPE));
(gdb)
149 return data;
(gdb)
64 reqData = packet.getData();
(gdb)
67 RemoteKVMSConfigData::setRemoteKVMSConfigData( &reqData );
(gdb) p reqData <==== 変数の内容を表示 昔に比べて賢くなったなぁ
$1 = {part = {{modified = false, remote_kvm = true, remote_storage = false, console_redirection = false, routingIP = "▒\000", netmask = "▒▒▒▒"}, {
modified = false, remote_kvm = true, remote_storage = false, console_redirection = false, routingIP = "▒\000\001", netmask = "▒▒▒▒"}, {modified = false,
remote_kvm = true, remote_storage = false, console_redirection = false, routingIP = "▒\000\002", netmask = "▒▒▒▒"}, {modified = false,
remote_kvm = true, remote_storage = false, console_redirection = false, routingIP = "▒\000\003", netmask = "▒▒▒▒"}}}
(gdb)

バグでプロセスが死んだら、gdbの外で通常に再起動して、attachをやり直せば良い。dirやブレークポイントは保持できる。