armv7l架构下core dump中空指针检查触发段错误的原因求解
问题根因分析
你提供的汇编代码和源码可以直接对应,崩溃点ldr r0, [r5, #0]刚好对应源码中if (gl_pClient == NULL)的判断逻辑,执行步骤如下:
- 指令
<+0>~<+10>计算共享库数据段基地址存入r3寄存器 - 指令
<+16> ldr r5, [r3, r2]从基地址加0x21c偏移的位置读取全局变量gl_pClient的值存入r5 - 指令
<+18>尝试读取gl_pClient指向的CClient对象的第一个成员,此时r5的值为0x1dddc,属于系统未映射的低地址区间,直接触发段错误。
核心问题是全局变量gl_pClient的值异常,既不是初始的NULL,也不是合法的对象指针,常见触发原因有3类:
- 共享库重定位错误:使用
dlopen加载共享库时参数配置错误、符号冲突,导致gl_pClient的地址计算错误,读取到的是偏移值而非实际变量值 - 内存越界篡改:其他执行逻辑存在野指针写、数组越界等问题,刚好改写了
gl_pClient所在的内存区域,把正常指针值覆盖为0x1dddc这个非法值 - 架构适配问题:编译共享库时指定的ARM架构参数和运行的armv7l设备不匹配,比如开启了设备不支持的指令集、地址对齐配置错误,导致全局变量加载逻辑异常
排查方案
- 首先在GDB中执行
x/w 0x6cd45d20(即r3+r2的计算结果,也就是gl_pClient的内存地址),确认该地址存储的值确实为0x1dddc,再执行info symbol 0x6cd45d20确认该地址对应gl_pClient变量,排除重定位错误 - 如果确认变量地址正确,给
gl_pClient加写入断点,追踪所有修改该变量的代码逻辑,定位把值篡改到0x1dddc的操作 - 检查
dlopen的flag参数,尝试加上RTLD_NOW参数让所有重定位在加载阶段完成,避免运行时才触发重定位错误
内容的提问来源于stack exchange,提问作者timonn
相关产品推荐
相关产品推荐

