gdb调试准备:
通过gcc的-g选项生成调试信息:
gcc -Wall -O2 -g xx.c 不经优化选择:gcc -Wall -O0 -g xx.c
如果使用Makefile构建,一般给CFLAGS中指定-g选项:
CFLAGS = -Wall -O2 -g
如果用configure脚本生成Makefile,可以这样用:
./configure CFLAGS = "-Wall -O2 -g"
在这里,-O是优化选项,如果打印出<value optimized out>, 可以在编译时添加-O0选项,意思是不进行编译优化,调试时就会顺畅,流程不会跳来跳去,发布项目时不要添加-O选项。gcc默认或添加-O2优化编译会提高程序运行速度。
gdb命令太多,举一个调试堆栈例子
1
2 #include <stdio.h>
3 #include <string.h>
4
5 void fun(char* input)
6 {
7 int a1 = 11;
8 int a2 = 22;
9 char buf[7];
10 strcpy(buf, (const char*)input);
11 printf("buf = %s\n", buf);
12 }
13
14 void main(int argc, char** argv)
15 {
16 fun(argv[1]);
17 }
使用info frame查看堆栈:
<pre name="code" class="cpp"> Breakpoint 3, fun (input=0xbffff805 "whatever") at stack.c:10
10 strcpy(buf, (const char*)input);
(gdb) info frame
Stack level 0, frame at 0xbffff5c0:
eip = 0x8048408 in fun (stack.c:10); saved eip 0x8048449
called by frame at 0xbffff5e0
source language c.
Arglist at 0xbffff5b8, args: input=0xbffff805 "whatever"
Locals at 0xbffff5b8, Previous frame's sp is 0xbffff5c0
Saved registers:
ebp at 0xbffff5b8, eip at 0xbffff5bc
(gdb)
解读下info frame:
Stack level 0, frame at 0xbffff5c0:
当前栈的起始位置0xbffff5c0
eip = 0x8048408 in fun (stack.c:10);saved eip 0x8048449
0x8048408表示当前的eip寄存器的值
0x8048449表示调用本函数的指令地址,也就是当前运行函数的调用处翻译为汇编后的地址。
called by frame at 0xbffff5e0
表示上一个栈帧的地址
Backtrace函数是追踪调用堆栈以及定位段错误。为了分析程序的bug,在程序出错时打印出函数的调用堆栈信息,可使用该函数:
int backtrace(void **buffer,int size)
这里调试时直接使用,backtrace命令可以在遇到断点而暂停执行时显示栈帧。此外,backtrace的别名还有where和info stack
<pre name="code" class="cpp"> (gdb) backtrace //显示所有栈帧
#0 fun (input=0xbffff805 "whatever") at stack.c:10
#1 0x08048449 in main (argc=2, argv=0xbffff684) at stack.c:16
(gdb) backtrace 2 //只显示开头的2个栈帧, -2表示只显示最后的2个栈帧
#0 fun (input=0xbffff805 "whatever") at stack.c:10
#1 0x08048449 in main (argc=2, argv=0xbffff684) at stack.c:16
(gdb) select-frame 0 //选择栈帧
(gdb) info frame //显示栈帧
Stack level 0, frame at 0xbffff5c0:
eip = 0x8048408 in fun (stack.c:10); saved eip 0x8048449
called by frame at 0xbffff5e0
source language c.
Arglist at 0xbffff5b8, args: input=0xbffff805 "whatever"
Locals at 0xbffff5b8, Previous frame's sp is 0xbffff5c0
Saved registers:
ebp at 0xbffff5b8, eip at 0xbffff5bc
(gdb) select-frame 1
(gdb) info frame
Stack level 1, frame at 0xbffff5e0:
eip = 0x8048449 in main (stack.c:16); saved eip 0xacdd36
caller of frame at 0xbffff5c0
source language c.
Arglist at 0xbffff5d8, args: argc=2, argv=0xbffff684
Locals at 0xbffff5d8, Previous frame's sp is 0xbffff5e0
Saved registers:
ebp at 0xbffff5d8, eip at 0xbffff5dc
命令太多时可以使用清屏命令:shellclear