用abort函数主动让进程abort/coredump, 有什么用处?------曾用此方法解决过一个低概率开机卡死的问题
2017-03-25 15:55
316 查看
之前玩过一段时间的嵌入式设备(如下叙述以手机为例)的软件开发, 当时出现了一个低概率问题: 系统开机会低概率卡死在某个模块中。 这个问题必须解决。
如果有问题的手机发布到用于手中, 假设概率万分之一, 那也非常高了, 想想某手机厂商的电池爆炸事件吧, 那是何等的低概率, 但还是发生了。
怎么定位呢? 我之前大致说过, 今天再来看看方法(如下简单示意):
思路很妙,现在回想起来, 确实有一点点激动。 其实, 我们也可以不用abort函数, 而利用一段必然core dump的代码来代替, 比如 int *p = ; *p = 0;
今天, 我们来看看abort函数的类似用途吧, 如下:
顺便复习了一下addr2line, 爽爽哒。 我们可以看到, 不用打印log, 不用单步调试, 就知道变量的值了。
但是, 千千万万要注意, 带有abort函数的代码玩玩不可提交到公共库, 否则有你好受的。
如果有问题的手机发布到用于手中, 假设概率万分之一, 那也非常高了, 想想某手机厂商的电池爆炸事件吧, 那是何等的低概率, 但还是发生了。
怎么定位呢? 我之前大致说过, 今天再来看看方法(如下简单示意):
// 伪代码, 不能直接运行 #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函数的代码玩玩不可提交到公共库, 否则有你好受的。
相关文章推荐
- 用kill -6 pid 主动杀死进程, 使进程abort/coredump, 有哪些用处?
- smartd进程是什么?他在开机启动不了的解决方法!
- Linux下tomcat作为守护进程运行(开机启动、以指定的用户运行、解决非root身份不能绑定1024以下端口的问题)的配置方法
- 解决高分辨率看网页字体太小问题的一个方法
- Windows Server 2003中的w3wp.exe进程大量占用cpu资源的各种问题解决方法
- SQL Server 2005:一个使用新创建的User的问题和解决方法
- 关于 clock_gettime() 的一个问题以及解决方法
- 关于Qt编译时问题的一个非常奇怪的解决方法
- [原创]SQL Server 2005:一个使用新创建的User的问题和解决方法
- 昨天我用了一个弱智的方法解决了一个弱智的问题
- DataGuard - 一个关于Physical Standby中recover问题的解决方法
- 在内网里用BT下载断线之迷,现在有一个真正的解决方法,有这问题的请进! (源至BTCHINA论坛)
- 蛙蛙推荐:整理一个树型问题的解决方法。
- 解决了一个每次开机都出现rundll错误的问题
- weblogic程序移植到jboss上的一个问题解决方法,j2ee,原创
- 使用ld的“-Ttext”选项时可能产生的一个问题的解决方法
- C#中保存GIF文件后透明背景问题的一个解决方法
- spring 中配置log4j输出日志常见的一个小问题解决方法
- DataGuard - 一个关于Physical Standby中recover问题的解决方法
- (转)Windows Server 2003中的w3wp.exe进程大量占用cpu资源的各种问题解决方法