alignment trap - not handling instruction..

2019-07-13 02:59发布

 

概述

开始编辑日期:2018年12月26号    最后更新日期:2018年12月26号 问题描述:近日,团队开发的示教器设备在现场使用时,小频次出现异常黑屏(程序进程死掉,嵌入式Linux正常运行)。下面的提示是前期好不容易捕获的一次告警信息:...Alignment trap:not handling instruction e1943f9f at [<0002b7b0>] ...Unhandled fault: alignment exception(0x001) at 0x00000086.  ##将此文章更新在博客里头的主要原因是,近几天发现CSDN知识库又TM的不能使用了,公司网络限制比较苛刻,没有其他地方存储查询到的网络资料。声明,本文章,绝不透露任何的涉及公司保密信息的内容,仅记录个人资料与心得,以方便排查解决问题。由于公司保密要求,上网限制等原因,不能进行贴图贴代码等操作,如有问题请直接留言交流。本人菜鸟一只,欢迎批评指正,相互交流。 参考文档: <1>非gdb, 在程序异常时打印backtrace的一种方案 ## http://blog.chinaunix.net/uid-20698826-id-4590296.html <2>linux addr2line 定位so库崩溃位置 ## http://www.cnblogs.com/zl1991/p/5893329.html <3>在Linux中如何利用backtrace信息解决问题 ## https://blog.csdn.net/jxgz_leo/article/details/53458366 <4>知识补充-GCC常用参数详解 ## https://www.cnblogs.com/zhangsir6/articles/2956798.html

直接backtrace方案

在参考文章<1>中,博主jsxthncn提到在进行编译时,要加入参数 -g -rdynamic //注意该参数是给链接器而不是编译器设置的。我用的是Qt集成开发环境,Makefile是使用qmake生成的,修改方式如下: CC    = arm-linux-gcc CXX   = arm-linux-g++ LINK   = arm-linux-g++ -g -rdynamic  ##only modify this line  

GDB + CoreDump 方案

问题起源

https://bbs.csdn.net/topics/390852706  //已有论坛问题(同我的问题描述)

arm-linux-gdb安装

搭建交叉调试环境 arm-linux-gdb配合gdbserver  ##  https://www.cnblogs.com/cherishui/p/4414013.html 博文中- 编译arm-linux-gdb 在gdb-7.8的解压目录下新建 arm-gdb,用于存放编译生成文件。 ./configure --target=arm-linux --prefix=/ -gdb/ 这里不要照搬/ -gdb/,第一中间不应该有空格(原谅我是菜鸟,否则执行报错)。--prefix是在指定生成目录。可使用下面的写法:--prefix=/usr/local/arm-gdb GDB下载 ## http://www.linuxfromscratch.org/blfs/view/7.6/general/gdb.html arm-GDB一些安装错误解决 https://blog.csdn.net/tiger15605353603/article/details/81296312 https://blog.csdn.net/capture_bbom/article/details/64437791 http://www.cnblogs.com/qingchen1984/p/5313383.html   //apt-get arm-linux-gdb编译完成后,可以不用make install,去上边指定的target目录下找就好了。在使用该gdb时,直接带着全路径使用也可以的。

GDB调试

将嵌入式系统中运行异常产生的core文件,拷贝回虚拟机(可直接放到交叉编译的target目录),然后在该目录下,执行Eg: # /usr/local/arm-gdb/bin/arm-linux-gdb yourAppName core-AppName-PID 执行完成后,可能并没有出现你要的信息,这时候继续执行GDB调试指令bt(即backtrace),进一步打印程序调用栈信息。到这里,我的问题,已经能追查到具体的行号啦...

解决程序后台运行不能生成core文件

问题描述  ## https://bbs.csdn.net/topics/392416550?page=1 https://www.cnblogs.com/nufangrensheng/p/3509262.html 楼主“愤怒的呆鱼”中提到的方案,确实可以解决后台运行程序崩溃时不生产core的问题,亲测可用,但是楼主代码中,将rlimit设置为RLIM_INFINITY(无限大),让我很头疼,我的嵌入式文件系统本来就不大,如果不限制core大小,一个core文件就高达80多兆,有点小承受不了。截止20181228没有找到其他解决办法,领导在催了,只能先放放,有了手段,但是还没有去真正解决问题呢...

问题处理

coredump函数调用栈显示,程序崩溃在: inline QString::QString(const QString &other) : d(other.d) { Q_ASSERT(&other != this); d->ref.ref(); } //其上一层调用 //伪代码 strList << iter->value().str1 << iter->value().str2..  这是QString的拷贝构造函数,自我复制,导致无限循环,最终致使程序栈溢出。关于拷贝构造函数请参考-百度百科:https://baike.baidu.com/item/%E6%8B%B7%E8%B4%9D%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0/9344013?fr=aladdin 机缘巧合,在帮同事处理问题时发现,错误的使用QMap的迭代器(如果iter时map.end() 则执行iter->value() 时,便会发生同样的异常-函数调用栈信息)。经过进一步排查,发现此处存在多线程同时遍历一个map的情况。QMap是可重入的(http://doc.qt.io/archives/qt-4.8/qchar.html)- Note: All functions in this class are reentrant. 但是Qt指导手册中并没有提到 iterator Class 是可重入的。(http://doc.qt.io/archives/qt-4.8/threads-reentrancy.html#reentrant)在官方文档中,可以看到,如果某个Qt类是可重入或线程安全的,会进行单独标记的。也就是说iterator应该是不可重入的。 Qt-隐式共享:https://blog.csdn.net/zhu_xz/article/details/6061201  GCC在C语言中内嵌汇编 asm __volatile__:https://blog.csdn.net/pbymw8iwm/article/details/8227839 AT&T与Intel汇编语法的比较:https://blog.csdn.net/happy987818/article/details/51557502 常用的汇编指令:https://blog.csdn.net/qq_33733970/article/details/78572733 C++Union的用法:https://blog.csdn.net/lincyang/article/details/6176642 关键信息: 使用C++联合,尤其是匿名联合,虽可以节省内存空间,但是也有一定的风险,如果通过一个不适当的数据成员获取当前对象的值!例如上面的ch、i交错访问,就是联合内存上存PartA的时候,却执行了PartB的访问。