标签:style blog http color os 使用 io strong ar
网上有很多Segmentation Fault的调试方法,下面这篇文件就很好
<Linux环境下段错误的产生原因及调试方法小结>
然而笔者在实际的使用中由于各种原因总觉得不够用
于是在网上找到了一种个人觉得更直接的方法
Segmentation Fault发生的时候,程序收到了信号11(SIGSEGV)
我们捕获该信号,然后利用事故发生时保存的寄存器现场加上栈信息定位到具体行
这里参考了< C/C++捕获段错误,打印出错的具体位置(精确到哪一行) >
使用其提供的头文件segvCatch.h
3. 实例程序
下面是测试用的实例程序 SegFault.c
1: #include "segvCatch.h"
2:
3: void SegFaultFunc()
4: {
5: int *p = NULL;
6: *p = 123;
7: }
8: void Func3()
9: {
10: SegFaultFunc();
11: }
12: void Func2()
13: {
14: Func3();
15: }
16: void Func1()
17: {
18: Func2();
19: }
20: int main()
21: {
22: initSegvCatch();
23: Func1();
24: return 0;
25: }
下面是编译和定位过程
[Jerry@ work]$ gcc SegFault.c -g -o SegFault -rdynamic [Jerry@ work]$./SegFault signal[11] catched when running code at 80488d6 signal[11] catched when running code at 80488b9 signal[11] catched when running code at 80488af signal[11] catched when running code at 80488a5 signal[11] catched when running code at 8048896 Aborted [Jerry@ work]$ addr2line 80488d6 80488b9 80488af 80488a5 8048896 -e ./SegFault -f main /home/Jerry/work/SegFault.c:23 Func1 /home/Jerry/work/SegFault.c:18 Func2 /home/Jerry/work/SegFault.c:14 Func3 /home/Jerry/work/SegFault.c:10 SegFaultFunc /home/Jerry/work/SegFault.c:6
可以看到最后依次显示了调用顺序
main() –> Func1() –> Func2() –> Func3() –> SegFaultFunc()
同时定位到具体出错的行(第六行)
值得注意是在编译时需要加上-g以获得调试信息()
由于笔者开发使用的系统架构是ARM,而上面的segvCatch.h只支持x86
故笔者在一番研究之后得到了基于ARM和MIPS的方法
关键点在于获取当前执行的指令的地址
对于X86,为EIP寄存器
对于ARM/MIPS,则为PC寄存器
其实际值可以查看工具链头文件ucontext.h来了解实际定义的保存方式
对于X86 为ucontext_t.uc_mcontext.gregs[REG_EIP] 对于ARM 为ucontext_t.uc_mcontext.arm_pc 对于MIPS 为ucontext_t.uc_mcontext.pc (未测试)
修改后的版本已上传至GitHub
https://github.com/sharmer/SomeDownload/tree/master/SegFault
标签:style blog http color os 使用 io strong ar
原文地址:http://www.cnblogs.com/hzl6255/p/3945809.html