GDB全过程详细讲解
摘自:https://blog.csdn.net/guo_lei_lamant/article/details/83787730
4. 堆栈
查看调用堆栈(call stack)无疑是调试过程中非常重要的事情。
(gdb) where # 查看调用堆栈 (相同作用的命令还有 info s 和 bt)
#0 test (a=4096, b=8192) at hello.c:5
#1 0x0804843b in main () at hello.c:13
(gdb) frame # 查看当前堆栈帧,还可显示当前代码
#0 test (a=4096, b=8192) at hello.c:5
5 int c = a + b;
(gdb) info frame # 获取当前堆栈帧更详细的信息
可以用 frame 修改当前堆栈帧,然后查看其详细信息。
(gdb) frame 1
#1 0x0804843b in main () at hello.c:13
13 int c = test(a, b);
(gdb) info frame
5. 变量和参数
(gdb) info locals # 显示局部变量
c = 0
(gdb) info args # 显示函数参数(自变量)
8. 进程
查看进程相关信息,尤其是 maps 内存数据是非常有用的。
(gdb) help info proc stat
Show /proc process information about any running process.
Specify any process id, or use the program being debugged by default.
Specify any of the following keywords for detailed info:
mappings – list of mapped memory regions.
stat – list a bunch of random process info.
status – list a different bunch of random process info.
all – list all available /proc info.
(gdb) info proc mappings # 相当于 cat /proc/{pid}/maps
process 22561
cmdline = ‘/home/yuhen/Learn.c/hello’
cwd = ‘/home/yuhen/Learn.c’
exe = ‘/home/yuhen/Learn.c/hello’
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0 /home/yuhen/Learn.c/hello
0x8049000 0x804a000 0x1000 0 /home/yuhen/Learn.c/hello
0x804a000 0x804b000 0x1000 0x1000 /home/yuhen/Learn.c/hello
0x8a33000 0x8a54000 0x21000 0x8a33000 [heap]
0xb7565000 0xb7f67000 0xa02000 0xb7565000
0xb7f67000 0xb80c3000 0x15c000 0 /lib/tls/i686/cmov/libc-2.9.so
0xb80c3000 0xb80c4000 0x1000 0x15c000 /lib/tls/i686/cmov/libc-2.9.so
0xb80c4000 0xb80c6000 0x2000 0x15c000 /lib/tls/i686/cmov/libc-2.9.so
0xb80c6000 0xb80c7000 0x1000 0x15e000 /lib/tls/i686/cmov/libc-2.9.so
0xb80c7000 0xb80ca000 0x3000 0xb80c7000
0xb80d7000 0xb80d9000 0x2000 0xb80d7000
0xb80d9000 0xb80da000 0x1000 0xb80d9000 [vdso]
0xb80da000 0xb80f6000 0x1c000 0 /lib/ld-2.9.so
0xb80f6000 0xb80f7000 0x1000 0x1b000 /lib/ld-2.9.so
0xb80f7000 0xb80f8000 0x1000 0x1c000 /lib/ld-2.9.so
0xbfee2000 0xbfef7000 0x15000 0xbffeb000 [stack]</pre>
9. 线程
可以在 pthread_create 处设置断点,当线程创建时会生成提示信息。
(gdb) c
Continuing.
[New Thread 0xb7e78b70 (LWP 2933)]
(gdb) info threads # 查看所有线程列表
- 2 Thread 0xb7e78b70 (LWP 2933) test (arg=0x804b008) at main.c:24
1 Thread 0xb7e796c0 (LWP 2932) 0xb7fe2430 in __kernel_vsyscall ()(gdb) where # 显示当前线程调用堆栈
#0 test (arg=0x804b008) at main.c:24
#1 0xb7fc580e in start_thread (arg=0xb7e78b70) at pthread_create.c:300
#2 0xb7f478de in clone () at …/sysdeps/unix/sysv/linux/i386/clone.S:130
(gdb) thread 1 # 切换线程
[Switching to thread 1 (Thread 0xb7e796c0 (LWP 2932))]#0 0xb7fe2430 in __kernel_vsyscall ()
(gdb) where # 查看切换后线程调用堆栈
#0 0xb7fe2430 in __kernel_vsyscall ()
#1 0xb7fc694d in pthread_join (threadid=3085405040, thread_return=0xbffff744) at pthread_join.c:89
#2 0x08048828 in main (argc=1, argv=0xbffff804) at main.c:36
10. 其他
调试子进程。
(gdb) set follow-fork-mode child
临时进入 Shell 执行命令,Exit 返回。
(gdb) shell
调试时直接调用函数。
(gdb) call test("abc")
使用 "--tui" 参数,可以在终端窗口上部显示一个源代码查看窗。
$ gdb --tui hello
查看命令帮助。
(gdb) help b
最后就是退出命令。
(gdb) q
和 Linux Base Shell 习惯一样,对于记不住的命令,可以在输入前几个字母后按 Tab 补全。
----------- 分隔线 ---------------
GDB 还有很多指令,功能也异常强大。不过对于熟悉了 VS 那种豪华 IDE 的人来说,这种命令行调试是种巨大的痛苦。尽管我个人建议多用 GDB,但也不反对用 GUI 调试器来加快调试进程。Nemiver 就不错,推荐一下。