gdb调试——堆栈

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





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值