加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何跟踪SIGFPE /算术异常

发布时间:2020-12-16 05:49:39 所属栏目:百科 来源:网络整理
导读:我有一个交叉编译的C应用程序,用于运行在ARM CortexA9处理器上的 Linux,该处理器与SIGFPE / Arithmetic异常崩溃.最初我以为是因为gcc的-O3标志引入了一些优化,但是我在调??试模式下构建它,它仍然崩溃. 我用gdb调试了应用程序,捕获异常,但不幸的是,操作触发异
我有一个交叉编译的C应用程序,用于运行在ARM CortexA9处理器上的 Linux,该处理器与SIGFPE / Arithmetic异常崩溃.最初我以为是因为gcc的-O3标志引入了一些优化,但是我在调??试模式下构建它,它仍然崩溃.

我用gdb调试了应用程序,捕获异常,但不幸的是,操作触发异常似乎也会垃圾堆栈,所以我无法获得任何关于我的代码中导致发生的地方的详细信息.我可以得到的唯一的细节是触发异常的操作(从以下堆栈跟踪):

3 raise()  0x402720ac   
    2 __aeabi_uldivmod()  0x400bb0b8    
    1 __divsi3()  0x400b9880

__aeabi_uldivmod()正在执行一个无符号的长时间划分和提醒,所以我尝试了强力的方法,并搜索我的代码可能使用该操作的地方,但没有太多的成功,因为它被证明是一个艰巨的任务.此外,我还试图检查潜在的部门为零,但代码基础却相当大,并检查每个部门的操作,这是一个麻烦和有点愚蠢的方法.所以必须有一个更聪明的方式来弄清楚发生了什么.

当调试器无法做很多帮助时,是否有任何技巧来追踪这种异常的原因?

更新:对十六进制数进行处理后,转储内存并进行堆栈取证(谢谢Crashworks)我在ARM编译器文档中遇到了这个gem(即使我没有使用ARM的编译器):

Integer division-by-zero errors can be trapped and identified by
re-implementing the appropriate C library helper functions. The
default behavior when division by zero occurs is that when the signal
function is used,or
__rt_raise() or __aeabi_idiv0() are re-implemented,__aeabi_idiv0() is
called. Otherwise,the division function returns zero.
__aeabi_idiv0() raises SIGFPE with an additional argument,DIVBYZERO.

所以我把一个断点放在__aeabi_idiv0(_aeabi_ldiv0)et Voila !,我完整的堆栈跟踪完全被丢弃.感谢大家的非常翔实的答案!

免责声明:“获奖”答案是单独和主观地考虑到我的调查工作的建议的重量,因为多个信息丰富,真正有用.

解决方法

我的第一个建议是打开一个记忆窗口,看着你的堆栈指针周围的区域,然后挖掘它,看看你是否可以找到附近没有破坏的堆栈框架,这可能会给你一个关于崩溃的地方的线索.通常堆栈垃圾只会烧掉几个堆栈帧,所以如果你看上去几百个字节,你可以通过损坏的区域,并得到代码的一般感觉.你甚至可以往下看堆栈,假设死亡函数在死亡之前可能会调用其他函数,因此内存中可能还存在一个指向当前IP的旧帧.

在评论中,我链接了一些演示幻灯片,说明了PowerPC上的技术 – 在类似的故障堆栈崩溃中,查看大约73-86的案例研究.显然,您的ARM的堆栈框架将不同,但一般原则成立.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读