文章目录
GDB最详细的文档请参考GDB Documentation。其中给出的关于GDB的简介非常精炼:
The purpose of a debugger such as GDB is to allow you to see what is going on “inside” another program while it executes—or what another program was doing at the moment it crashed.
GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:
- Start your program, specifying anything that might affect its behavior.
- Make your program stop on specified conditions.
- Examine what has happened, when your program has stopped.
- Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.
使用GDB进行调试时,为了查看完整的符号信息,在编译程序时需要加上选项-g -O0
,以保留调试符号信息。比如编译 redis 时,我们需要在make时如下操作:
make CFLAGS="-g -O0"
如果是C++的程序则使用编译器选项CXXFLAGS
。
启动GDB调试
有三种方法启动GDB调试:
gdb elf-file
—— 直接调试目标程序gdb -p pid
—— 附加到某个正在执行的进程gdb elf-file core
—— 调试coredump产生的core文件
当我们想要调试某个正在运行的进程而不想重新启动它以致于实时数据丢失,则可以将调试器附加(attach)到这个进程。比如我们的系统上有redis服务器正在运行,进程号时31055:
ps -ef | grep redis
book 31055 2554 0 03:41 ? 00:00:00 redis-server *:6379
那么通过指令sudo gdb -p 31055
就可以attach到redis进程:
......
Attaching to process 31055
[New LWP 31056]
[New LWP 31057]
[New LWP 31058]
[New LWP 31059]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f53c3d9fd67 in epoll_wait (epfd=5, events=0x7f53c3925b40,
maxevents=4192, timeout=100) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
30 ../sysdeps/unix/sysv/linux/epoll_wait.c: No such file or directory.
此时调试器会将进程暂停,待我们完成调试后,可以输入detach
指令使进程继续正常执行。
coredump的设置与调试
如果程序崩溃时产生了核心转储文件“core”(比如出现段错误、栈溢出),则会使相关问题的调试工作顺利许多。但首先我们需要通过ulimit -a
指令来查看当前Linux环境是否允许产生core文件: