GDB远程调试(二)之用gdb解决segmentation-fault段错误,看gdb的使用(嵌入式)

最近在调试代码的时候闹人的segmentation-fault段错误,又来烦人了抓狂,不过代码都是自己写的 ,有事也是作茧自缚,自作自受,先自责下敲打


来看看在串口段错误给了我们什么信息:


可以看出 Fault addr=0x328,出错的地址在 0x328,这个哪 啊?可惜backtrace没有给出execution path,哎,也不知道出在哪行代码了。得,自己发掘吧。


这里我们可以先用addr2line工具看看能否找出出错行,



只给出几个问号,鸡毛都没有,这可能有两种情况,一是编译的时候没加-g选项,另一个原因是0x328可能是系统函数的调用地址?反正就是没有什么信息。


那么还是编译的时候先把-g加上吧,然后把gdb请出来。我们使用的是嵌入式环境,需要使用交叉编译的gdb工具,这个过程就不说了,可以看另外一篇文章。


http://blog.csdn.net/mantis_1984/article/details/27494579


在target端用gdbserver 把应用程序挂起,监控:

./arm-arago-linux-gnueabi-gdbserver 192.168.1.100:2000 ./my_app &

然后在server端启动gdb:


然后重复刚才出错的时的操作,看看GDB会抓到什么错误信息:


好,gdb捕捉到了这个段错误信息,接下来看看栈回溯信息:


frame 0貌似没有什么信息展示出来,那么看看frame 1


可以看到frame 1调用栈在代码memcpy处进入的下一级 frame 0, 然后出错,那基本上可以锁定就是“

memcpy();这一行代码出现的问题,分别把变量dst和pst 打印出来,此时发现pst是不能访问的内存,且此地址正是0x328,也就是前面所说串口包段错误的地址。

这句代码貌似没什么问题,此时分析问题就要结合代码的上下文以及其调用关系了。我们通过栈回溯可以追查到到底哪里调用的这段代码。


代码太长,截取一段说明问题出在哪里,调用log_list_get_one_log后,获取一条日志在oneNode里,但是链表中的oneNode->next也被获取出来了,

下面在创建本地链表时给pst->next=NULL本没有问题,可以后面的memcpy后把oneNode->next也赋值给了pst->next,这是我们不愿意看到的,因为当本地释放

pst后,会将glb_h_alarm_log中的那个next指针所指向的内存也释放掉了,所以再次用获取glb_h_alarm_log时会出现内存不可访问的段错误(上面的0x328)不能

访问,因为在外面已经被释放。

所以说在使用链表,尤其是复制别的链表时,一定要小心处理这个next指针,很危险的。所以上面代码应该改成 memcpy这一行与pst->next=NULL交换,就没有问题了。

问题比较隐蔽,没有gdb,这个问题估计很难发现。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值