一、gdb是什么
GDB 是 GNU Project Debugger 的缩写,是一款强大的命令行调试工具,支持多种编程语言,如C、C++、Objective-C、Pascal等等,常用于软件开发和调试。它可以让程序在运行时停下来,检查程序的状态,以及变量的值,控制程序的运行和内存的使用。
二、堆栈的作用与调试
堆是一个保存在电脑内存(RAM)中的一块区域,程序运行时,需要时刻对堆中的内存进行分配和释放,如果分配和释放的不当,会导致内存出现一系列问题,如野指针、内存泄露等。堆栈是一种用于解决内存问题的机制。在函数调用时,每个函数都有一个堆栈帧(Stack Frame)用于保存程序状态,参数和变量。当函数调用结束时,堆栈帧就会被销毁,返回到调用该函数的帧中继续执行。在进行程序调试时,堆栈的信息对于找到问题具有很大的帮助。
三、使用gdb查看堆栈
1.设置堆栈跟踪
使用 gdb 调试程序时,可以设置堆栈跟踪,以便更好的查看和分析在程序中发生的错误。 在 gdb 命令行中使用 command 命令,加上 bt 参数,就可以打开堆栈跟踪功能。更多的堆栈选项可以使用 help backtrace 命令来查看。例如:
(gdb) command 1 >bt >end
2.查看堆栈信息
调试程序时,常常需要查看堆栈信息以帮助判断问题。在 gdb 命令行中,使用 bt (backtrace)命令可以打印出当前进程的堆栈信息。指定参数 n 表示打印最近的 n 次调用,不指定参数则表示打印所有调用。例如:
(gdb) bt 5 #0 0x00000000004011d6 in main () at test.c:5 #1 0x00000000004011c0 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x00000000004010c9 in _start () #3 0x0000000000000000 in ?? ()
3.查看局部变量
在 gdb 命令行中,还可以查看当前所在堆栈帧中的局部变量信息。使用命令 frame n (n 为框架的编号) 可以切换到指定堆栈帧中。使用 info locals 命令可以查看当前堆栈帧中的局部变量信息。例如:
(gdb) frame 1 #1 0x08048408 in func2 () at test.c:10 10 int n = 0; (gdb) info locals n = 0
4.设置断点和跟踪变量
除了上述堆栈命令,gdb 还提供了设置断点和跟踪变量的功能。使用 command 命令,以及 breakpoint 和 watchpoint 命令可以通过条件语句来定义在满足条件时停止程序执行,同时记录一些关键变量的值。例如:
(gdb) break func1 if n > 10 (gdb) watch n (gdb) backtrace #0 func1 (n=11) at test.c:5 #1 0x08048436 in main () at test.c:17
5.使用gdb调试堆溢出问题
堆栈问题经常是程序运行时出现的问题。在堆栈溢出的情况下,我们可以使用 gdb 通过查看堆栈信息,找出问题所在,并调试解决问题。例如:
int main () { char *p = malloc(8); strcpy(p, "123456"); printf("%s", p); return 0; }
在程序运行时,当 strcpy 拷贝超过 8 字节时,将会导致堆栈溢出问题。使用 gdb 进行调试,一步一步跟踪并查看堆栈信息,可以找到这个问题的根源。例如:
(gdb) run Starting program: /root/test [New Thread 2247] [New Thread 2248] 123456Program received signal SIGSEGV, Segmentation fault. __strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:294 294 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory. (gdb) bt #0 __strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:294 #1 0x000000000040117b in main () at test.c:7
6、使用Core Dump 进行Debug
GDB 还支持使用 Core Dump 进行调试,Core Dump 是指在程序运行崩溃时会产生一份程序内存快照,并将其写到磁盘上。当需要对程序进行调试时,可以将 Core Dump 文件加载到 GDB 中来分析。 为了启用 Core Dump,需要先执行以下命令:
- ulimit -c unlimited:该命令设置可以生成无限量的 Core Dump 文件
- echo "/var/core.%p.%u.%h.%t" > /proc/sys/kernel/core_pattern
- sysctl -w kernel.core_uses_pid=1,以 PID 来区分 Dump 文件
gdb
四、小结
使用 gdb 查看堆栈可以有效的检测到堆栈溢出问题,同时也对程序中的其他问题解决具有帮助,gdb 是一个强大的调试工具,掌握其使用方法能够大大提高程序员的调试效率。