在嵌入式设备中启用core dump转储
- 2022 年 4 月 1 日
- 筆記
- core dump, getrlimit, linaro, RLIM_INFINITY, RLIMIT_CORE, setrlimit, ulimit, 嵌入式
最近尝试在嵌入式设备中实现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更加优雅。