使用GDB调试Core文件时,如何区分SIGSEGV源于数据还是代码段访问?
如何通过GDB判断SIGSEGV源于数据段还是代码段访问错误
触发SIGSEGV的示例场景
数据段访问错误场景
int x = NULL; int y = *x;
代码段访问错误场景
int (*x)() = NULL; int y = x();
上述两段代码都会触发SIGSEGV(段错误)信号:前者是对空指针解引用,属于非法访问数据段内存;后者是试图调用空指针指向的函数,本质是跳转到非法代码地址执行,属于非法访问代码段内存。
无符号文件时,用GDB调试Core文件的判断方法
看当前执行的指令类型
加载Core文件后,用x/i $pc指令查看当前触发错误的机器指令:- 如果是
mov、load这类数据读写类指令,说明是数据段访问出错; - 如果是
call、jmp这类控制流跳转/调用指令,说明是代码段访问出错。
- 如果是
查错误地址的内存属性
用info proc mappings(部分系统可用vmmap)查看进程的内存映射表,定位触发错误的地址(GDB会直接显示错误地址,比如0x0000000000000000):- 要是地址落在
r--/rw-这类数据属性的内存区域(或完全不在合法映射区),且对应数据读写指令,就是数据段错误; - 要是地址落在
r-x这类代码属性的内存区域(或非法区域),且对应跳转/调用指令,就是代码段错误。
- 要是地址落在
读GDB的错误提示
GDB加载Core文件后会直接输出错误相关信息,比如:Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000000000000000 in ?? ()
此时再用x/i $pc看指令,若是数据访问类指令,就是数据段错误;若是调用/跳转指令,就是代码段错误。
内容的提问来源于stack exchange,提问作者tinkerbeast
相关产品推荐
相关产品推荐

