CoreDump调试指南:5、嵌入式CoreDump调试
嵌入式系统中coredump如何使用
目录
随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记下来。存在很多在特殊情况下有一点用处的技巧,用的不多的技巧可能一个星期就忘了。
想了很久想通过一些手段把这些事情记录下来。也尝试过在书上记笔记,这也只是一时的,书不在手边的时候那些笔记就和没记一样,不是很方便。
很多时候我们遇到了问题,一般情况下都是选择在搜索引擎检索相关内容,这样来的也更快一点,除非真的找不到才会去选择翻书。后来就想到了写博客,博客作为自己的一个笔记平台倒是挺合适的。随时可以查阅,不用随身携带。
同时由于写博客是对外的,既然是对外的就不能随便写,任何人都可以看到。经验对于我来说那就只是经验而已,公布出来说不一定我的一些经验可以帮助到其他的人。遇到和我相同问题时可以少走一些弯路。
既然决定了要写博客,那就只能认真去写。不管写的好不好,尽力就行。千里之行始于足下,一步一个脚印,慢慢来
,写的多了慢慢也会变好的。权当是记录自己的成长的一个过程,等到以后再往回看时,就会发现自己以前原来这么菜😂。
本系列博客所述资料均来自互联网
,并不是本人原创(只有博客是自己写的)。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,没有为自己谋取私利的想法
。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。
准备工作
测试源码
这边还是使用前面文章使用到的示例程序。
ubuntu@kvm:~/CoreDump$ vim ./TestCoreDump.c
#include "stdio.h"
#include "stdlib.h"
void dumpCrash()
{
char *pStr = "test coredump";
free(pStr);
}
int main()
{
dumpCrash();
return 0;
}
编译
使用设备平台的交叉编译器,编译出可执行文件,注意需要在编译时指定-ggdb3
才会生成可供调试的二进制文件。
通过adb将交叉编译后的可执行文件,导入到嵌入式设备中。
zac@ubuntu:~/CoreDump$ ls
TestCoreDump
zac@ubuntu:~/CoreDump$ file TestCoreDump
./TestCoreDump: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=19731a7f35671446e4e8157202b3e5a05173253d, for GNU/Linux 3.2.0, with debug_info, not stripped
zac@ubuntu:~/CoreDump$ adb push ./TestCoreDump /usrdata/CoreDump
./TestCoreDump:1 file pushed, 0 skipped. 15.6 MB/s (46892 bytes in 0.003s)
获取CoreDump文件
adb进入到设备控制台,设置ulimit -c unlimited
。执行可执行文件,获取生成的core
文件。
zac@ubuntu:~/CoreDump$ adb shell
/ # cd /usrdata/CoreDump
/usrdata/CoreDump # ls
TestCoreDump
/usrdata/CoreDump # ulimit -c unlimited
usrdata/CoreDump # ./TestCoreDump
Segmentation fault (core dumped)
/usrdata/CoreDump # ls
TestCoreDump core.2098
调试
嵌入式平台中存在两种CoreDump的调试方式。一种是把GDB编译到设备中,这种调试方式和PC上并无太多区别。另一种则是把设备生成的core文件导出,使用交叉编译工具链中的gdb工具在PC上面运行。
在设备中调试
编译gdb
不同的嵌入式平台编译gdb的方法不一样,这里以sdx6x为例。
gdb
占用较大的空间,大约5MB
。默认情况下并不会被编译到rootfs
中。
如果需要使用gdb
,则需要修改sdxlemur-xxxxxx-prop-image.inc
文件,在其中添加一行IMAGE_INSTALL += "gdb"
即可打开gdb
的编译选项。
// apps_proc/poky/meta-qti-xxxxx-prop/recipes-products/images/sdxlemur/sdxlemur-xxxxx-prop-image.inc
.............
IMAGE_INSTALL += "gdb"
.............
在yocto
编译系统中,同时还会检查开源组件的授权情况,编译gdb
会报如下错误。大概意思就是存在不兼容的开源授权软件包。
NOTE: Resolving any missing task queue dependencies
ERROR: Nothing RPROVIDES 'gdb' (but /Qualcomm/zac.chen/Perforce/SW9_zac.chen_ap_221121/depot3/Qualcomm/SDX6X/MCU_R05/apps_proc/poky/meta-qti-bsp/recipes-products/images/qti-mbb-minimal-image.bb RDEPENDS on or otherwise requires it)
gdb was skipped: it has incompatible license(s): GPL-3.0 LGPL-3.0
NOTE: Runtime target 'gdb' is unbuildable, removing...
Missing or unbuildable dependency chain was: ['gdb']
ERROR: Required build target 'qti-mbb-minimal-image' has no buildable providers.
Missing or unbuildable dependency chain was: ['qti-mbb-minimal-image', 'gdb']
gdb
使用的是GPL-3.0
协议,而该协议存在传染性,软件中只要使用了包含GPL-3.0
协议的开源软件,则该软件也必须开源。
只是内部调试则可以临时去除这部分限制使用,但是不可默认启用分发。修改qti-distro-nogplv3.inc
文件注释掉INCOMPATIBLE_LICENSE
即可,切记
该修改不可提交。
//apps_proc/poky/meta-qti-distro/conf/distro/include/qti-distro-nogplv3.inc
# INCOMPATIBLE_LICENSE += "GPL-3.0 LGPL-3.0 AGPL-3.0"
解析CoreDump数据
使用方法其实和Ubuntu上面没太大区别,gdb -c <CoreDumpFile> <app>
即可正确解析。
root@sdxlemur:/usrdata/CoreDump# gdb -c ./core.2098 ./TestCoreDump
GNU gdb (GDB) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "arm-oe-linux-gnueabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./TestCoreDump...
warning: exec file is newer than core file.
[New LWP 1776]
Core was generated by `./TestCoreDump'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0xa6f03f30 in ?? () from /lib/libc.so.6
执行后发现有一个报错,提示找不到C标准库的动态链接库。我们不需要调试C标准库的堆栈信息,这里可以直接忽略该错误,只需要关注应用的堆栈即可。
bt
命令用于展开堆栈信息,到这里其实就已经知道了代码出现Dump
的位置了。in dumpCrash () at TestCoreDump.c:6
则代表,Dump
问题位于TestCoreDump
文件的第六行,问题函数是dumpCrash
。
(gdb) bt
#0 0xa6efbf30 in ?? () from /lib/libc.so.6
#1 0x0040f530 in dumpCrash () at TestCoreDump.c:6
#2 0x0040f54c in main () at TestCoreDump.c:11
在上位机中调试
在设备中调试实际上还是有一点不方便的,默认情况下gdb并不会被编译到rootfs中,这就需要去改源码重新编译才能使用gdb去调试。
这里我们其实比较推荐使用第二种方案,就是使用交叉编译工具链中的gdb工具。这个工具可以在PC上解析设备的CoreDump文件。
配置环境变量
首先需要找到交叉编译工具链中的gdb调试工具,这个可以在编译后的产物中找到。最简单的方法就是直接拿OPEN_SDK
的编译工具链。
zac@ubuntu:~/CoreDump$ source ~/ql_crosstools/ql-cs-gcc930-v1-toolchain/environment-setup-armv7at2hf-neon-oe-linux-gnueabi
zac@ubuntu:~/CoreDump$ which arm-oe-linux-gnueabi-gdb
/home/zac/ql_crosstools/ql-cs-gcc930-v1-toolchain/gcc/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gdb
解析CoreDump数据
可以通过adb pull
命令把设备中的可执行文件和core文件导出到上位机中。
zac@ubuntu:~/CoreDump$ adb pull /usrdata/CoreDump/core.2098 ./
zac@ubuntu:~/CoreDump$ adb pull /usrdata/CoreDump/TestCoreDump ./
zac@ubuntu:~/CoreDump$ ls
core.2098 TestCoreDump
使用方法都一样的,需要注意的是,这里使用的是arm-oe-linux-gnueabi-gdb
而不是gdb
。
zac@ubuntu:~/CoreDump$ arm-oe-linux-gnueabi-gdb -c core.2098 ./TestCoreDump
GNU gdb (GDB) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-qtisdk-linux --target=arm-oe-linux-gnueabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./TestCoreDump...
[New LWP 2098]
warning: Could not load shared library symbols for 2 libraries, e.g. /lib/libc.so.6.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Core was generated by `./TestCoreDump'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0xa6efbf30 in ?? ()
bt
命令用于展开堆栈信息,到这里其实就已经知道了代码出现Dump
的位置了。in dumpCrash () at TestCoreDump.c:6
则代表,Dump
问题位于TestCoreDump
文件的第六行,问题函数是dumpCrash
。
(gdb) bt
#0 0xa6efbf30 in ?? ()
#1 0x0040f530 in dumpCrash () at TestCoreDump.c:6
#2 0x0040f54c in main () at TestCoreDump.c:11
那么本篇博客就到此结束了,这里只是记录了一些我个人的学习笔记,其中存在大量我自己的理解。文中所述不一定是完全正确的,可能有的地方我自己也理解错了。如果有些错的地方,欢迎大家批评指正。如有问题直接在对应的博客评论区指出即可,不需要私聊我。我们交流的内容留下来也有助于其他人查看,说不一定也有其他人遇到了同样的问题呢😂。
更多推荐
所有评论(0)