您的位置:首页 > 其它

用abort函数主动让进程abort/coredump, 有什么用处?------曾用此方法解决过一个低概率开机卡死的问题

2017-03-25 15:55 316 查看
       之前玩过一段时间的嵌入式设备(如下叙述以手机为例)的软件开发, 当时出现了一个低概率问题: 系统开机会低概率卡死在某个模块中。 这个问题必须解决。

       如果有问题的手机发布到用于手中, 假设概率万分之一, 那也非常高了, 想想某手机厂商的电池爆炸事件吧, 那是何等的低概率, 但还是发生了。

       怎么定位呢? 我之前大致说过, 今天再来看看方法(如下简单示意):

// 伪代码, 不能直接运行
#include <iostream>
using namespace std;

void startAAA()
{
// 启动AAA模块 ...
}

void myThreadFun() // 线程函数
{
Sleep(1000 * 300); // 停留5分钟

printf("creat core");
createCore(); // 产生core文件, 一般伴随着重启手机, 所以就不显式调用rebootCellphone了
}

int main()
{
createTestThread(myThreadFun); // 创建线程

printf("flag1");

startAAA(); // 低概率卡死在此处

printf("flag2");

rebootCellphone(); // 重启手机

// ...

while(1);

return 0;
}
       通过不停地自动重启手机来定位, 如果卡死, 就会进入线程函数, 主动产生core, 便于分析, 最后定位出了问题, 搞了一个星期后, 最后定位出了问题: 调用某第三方基础库时, 没有按要求初始化。

       思路很妙,现在回想起来, 确实有一点点激动。  其实, 我们也可以不用abort函数, 而利用一段必然core dump的代码来代替, 比如 int *p = ; *p = 0;

       今天, 我们来看看abort函数的类似用途吧, 如下:

#include <iostream>
#include <cmath>
using namespace std;

struct Point
{
int x;
int y;
};

int main()
{
Point po;
po.x = 1;
po.y = 2;
float distance = sqrt(po.x * po.x + po.y * po.y);

abort();
return 0;
}
      编译、运行并调试:

xxxxxx $ g++ test.cpp -g && ./a.out
Aborted (core dumped)
xxxxxx $
xxxxxx $
xxxxxx $
xxxxxx $ gdb a.out core
GNU gdb 6.6
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i586-suse-linux"...
Using host libthread_db library "/lib/libthread_db.so.1".

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libonion.so...done.
Loaded symbols for /lib/libonion.so
Reading symbols from /usr/lib/libstdc++.so.6...done.
Loaded symbols for /usr/lib/libstdc++.so.6
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libgcc_s.so.1...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/libpthread.so.0...done.
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./a.out'.
Program terminated with signal 6, Aborted.
#0  0xb7d22aa6 in raise () from /lib/libc.so.6
(gdb) bt
#0  0xb7d22aa6 in raise () from /lib/libc.so.6
#1  0xb7d241b3 in abort () from /lib/libc.so.6
#2  0x0804867c in main () at test.cpp:18
(gdb) f 2
#2  0x0804867c in main () at test.cpp:18
18              abort();
(gdb) i locals
po = {x = 1, y = 2}
distance = 2.23606801
(gdb) q
xxxxxx $ addr2line -e a.out 0x0804867c
/data/home/erickeyli/test.cpp:18
xxxxxx $


       顺便复习了一下addr2line,  爽爽哒。 我们可以看到, 不用打印log, 不用单步调试, 就知道变量的值了。

       但是, 千千万万要注意, 带有abort函数的代码玩玩不可提交到公共库, 否则有你好受的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐