GDB(十)--調試正在運行的進程
我編寫了一個循環:
long i;
for (i = 0; i < 999999; i++) {
mt.a += 1;
sleep(1);
}
把它編譯成a.out,并在后臺執行它:./a.out &
[1] 2570
然后用命令gdb ./a.out 2570可以附加到這個進程上。被時進程會中斷。
或者在GDB里輸入attach 2570同樣可以附加到進程。
輸入bt來查看棧
(gdb) bt
#0 0x008e9416 in __kernel_vsyscall ()
#1 0x003bb900 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
#2 0x003bb71f in sleep () from /lib/i386-linux-gnu/libc.so.6
#3 0x0804845d in main () at ptype_struct.c:22
可以看到程序正中斷在系統調用vsyscall上。用frame 3進入main函數的棧框架并打印i的值,
(gdb) frame 3
#3 0x0804845d in main () at ptype_struct.c:22
22 sleep(1);
(gdb) p i
$1 = 153
next可以執行下一行。
(gdb) next
Single stepping until exit from function __kernel_vsyscall,
which has no line number information.
0x003bb900 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
設置i的值。
(gdb) p i = 999999
$3 = 999999
detach可以分離進程。
(gdb) detach
Detaching from program: /home/tommy/tmp/a.out, process 2570
(gdb) q
[1]+ 完成 ./a.out
如果被調試的進程沒有調試信息:
$ strip ./a.out
$ ./a.out &
[1] 2603
tommy:~/tmp$ gdb
gdb> attach 2603
(gdb) bt
#0 0x00b0f416 in __kernel_vsyscall ()
#1 0x00721900 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
#2 0x0072171f in sleep () from /lib/i386-linux-gnu/libc.so.6
#3 0x0804845d in ?? ()
#4 0x0069e113 in __libc_start_main () from /lib/i386-linux-gnu/libc.so.6
#5 0x08048351 in ?? ()
函數名沒有被打印。
注意GDB其實可以看作是ptrace系統調用的前端。ptrace專門用來觀察和控制另一個進程的執行。觀察別的進程可能需要恰當的權限,比如超級用戶。不要去調試init進程,不然可能會很傷。我不小心把它殺掉,電腦直接黑屏。