在嵌入式设备中启用core dump转储

  最近尝试在嵌入式设备中实现core dump转储,发现没想象中那么复杂,但还是走了一些弯路,而且网上没有真正给我一站式解决方案的帖子。因此我在此给出自己摸索出来的解决办法。

 

  首先是编译内核时需要开启core dump功能,比如我们项目中SOC厂商使用的是linaro,一般都是打开的,我们可以确认一下。如下图:

  

 

  有了这个前提之后呢,我们还需要给进程赋予core dump功能资源使用能力。

  一般linux发行版是使用ulimit -c unlimited来实现,关键我们嵌入式设备它没有这个命令。

  不过没关系,我们可以使用代码来实现。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <sys/resource.h>
 4 
 5 int main() {
 6     struct rlimit rl;
 7     ::getrlimit(RLIMIT_CORE, &rl);
 8     std::cout << "before rlim_cur = " << rl.rlim_cur << " rlim_max = " << rl.rlim_max << std::endl;
 9 
10     // 这两句代码就等于ulimit -c unlimited
11     rl.rlim_cur = RLIM_INFINITY;
12     ::setrlimit(RLIMIT_CORE, &rl);
13 
14     ::getrlimit(RLIMIT_CORE, &rl);
15     std::cout << "after rlim_cur = " << rl.rlim_cur << " rlim_max = " << rl.rlim_max << std::endl;
16     char* str = nullptr;
17     std::strcpy(str, "crash you");
18     std::cout << str << std::endl;
19     return 0;
20 }

  (当然,ulimit -c unlimited网上解释是针对当前session而非单个进程,而上述代码针的作用域我就不清楚了,反正当前进程是可以的)

 

  接下来我们进入嵌入式设备环境,先设置一下崩溃的core文件位置(如果不设置的话默认是工作路径的core)。

sysctl -w "kernel.core_pattern=/tmp/core.%e.%t"

 

  最后我们运行可以产生段错误的程序,并尝试使用gdb对其核心转储进行分析。

  

  (从上图输出也可以看出,默认进程能够用于core dump功能的资源配额是0。这也是一般情况下进程崩溃不产生core文件的原因)

 

  有了core dump功能,我们就可以进行很多操作了,比起使用gdb或gdbserver手动运行进行调试来盯着看,显然使用core dump更加优雅。