在嵌入式Linux开发中,使用core dump来调试程序crash的问题。
需要程序crash时的内存dump文件,还有当前正在执行的程序,然后在host主机上执行GDB。
简单的说,在目标板上生成core dump文件,使用scp命令将文件copy到Ubuntu上,然后使用交叉编译环境的gdb来调试。
比如:
$ arm-poky-linux-gdb app coredump-app
但这时使用交叉编译工具链的gdb来调试目标板上的程序,需要使用目标板上头文件和库文件才行,不然没法完整解析这个core dump文件里面的符号。
这时就会提示:
warning: Could not load shared library symbols for 14 libraries, e.g. /lib/libpthread.so.0.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
那解决的办法,按照提示,一种方法是设置library path,一种是设置sysroot。
第一种方法,可能要设置多个path,而第二种方法更加简便快捷。
下面举个例子,在gdb时设置我环境下的sysroot:
(gdb) set sysroot /home/usrname/ingenic/buildroot/output/host/mipsel-buildroot-linux-gnu/sysroot
这是使用北京君正芯片开发时设置的路径。
然后这时候继续使用gdb下的命令,就能查看调试信息了:
(gdb) bt
。。。。。。
#9 0x0057582c in sigsegv_handler(int) ()
#10 <signal handler called>
#11 0x006c1cec in ClassA::Func4(char const*, unsigned char*, int, int) ()
#12 0x006c1eec in ClassA::Func3(char const*, unsigned char*, int) ()
#13 0x006c2248 in ClassA::Func2() ()
#14 0x0058a7d4 in ClassA::Func1(bool) ()
#15 0x0058a454 in ClassA::MainLoop() ()
#16 0x005730d4 in main ()
那这个sysroot是什么东东呢?
sysroot是你的目标文件系统的一个缩减版本,它只需要包含你要编译/链接的库和头文件。设置系统根的方法有很多,其中一种是将目标机上的/usr和/lib目录复制到主机文件系统上的某个地方。你也可以用NFS(网络文件系统)挂载目标文件系统到本地的某个地方。
sysroot就是一个存放头文件和库文件的根目录,它通常对应某一个执行环境,比如你的交叉工具链里就会有自己的sysroot。
GCC系列编译器接受一个"--sysroot=dir "参数,用来指定系统根目录的路径。检查你的交叉编译器的文档,了解如何正确设置你的编译器,当传递include或library目录时,你可能需要采取额外的步骤来使用sysroot。设置dir作为头文件和库的逻辑根目录。一般不设置情况下,编译器通常会在/usr/include中搜索头文件,在/usr/lib中搜索库,使用这个编译选项后,那么它将搜索dir/usr/include和dir/usr/lib。
那我们使用交叉编译工具链编译程序时,就可以指定这个sysroot参数,否则可能没有需要的头文件和库,导致无法编译。
比如一个使用yocto来构建的Linux项目,它的工具链如下:
$ ls /opt/poky-my/ver_no/sysroots
cortexa7t2hf-neon-poky-linux-gnueabi x86_64-pokysdk-linux
这里有两个sysroot,一个是我们主机使用的环境,在Linux/Ubuntu上,运行交叉编译程序,使用的是x86平台的库和头文件。
$ ls ./x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/
arm-poky-linux-gnueabi-addr2line arm-poky-linux-gnueabi-dwp arm-poky-linux-gnueabi-gcc-nm arm-poky-linux-gnueabi-gdb arm-poky-linux-gnueabi-ld.gold arm-poky-linux-gnueabi-ranlib
arm-poky-linux-gnueabi-ar arm-poky-linux-gnueabi-elfedit arm-poky-linux-gnueabi-gcc-ranlib arm-poky-linux-gnueabi-gdb-add-index arm-poky-linux-gnueabi-lto-dump arm-poky-linux-gnueabi-readelf
arm-poky-linux-gnueabi-as arm-poky-linux-gnueabi-g++ arm-poky-linux-gnueabi-gcov arm-poky-linux-gnueabi-gprof arm-poky-linux-gnueabi-nm arm-poky-linux-gnueabi-size
arm-poky-linux-gnueabi-c++filt arm-poky-linux-gnueabi-gcc arm-poky-linux-gnueabi-gcov-dump arm-poky-linux-gnueabi-ld arm-poky-linux-gnueabi-objcopy arm-poky-linux-gnueabi-strings
arm-poky-linux-gnueabi-cpp arm-poky-linux-gnueabi-gcc-ar arm-poky-linux-gnueabi-gcov-tool arm-poky-linux-gnueabi-ld.bfd arm-poky-linux-gnueabi-objdump arm-poky-linux-gnueabi-strip
$ ls ./x86_64-pokysdk-linux/lib/
ld-2.33.so libBrokenLocale-2.33.so libdl-2.33.so libm.so.6 libncursesw.so.5.9 libnss_compat.so.2 libnss_files.so.2 libresolv.so.2 libtinfo.so.5.9
ld-linux-x86-64.so.2 libBrokenLocale.so.1 libdl.so.2 libmvec-2.33.so libnsl-2.33.so libnss_dns-2.33.so libpthread-2.33.so librt-2.33.so libutil-2.33.so
libanl-2.33.so libc-2.33.so libgcc_s.so.1 libmvec.so.1 libnsl.so.1 libnss_dns.so.2 libpthread.so.0 librt.so.1 libutil.so.1
libanl.so.1 libc.so.6 libm-2.33.so libncursesw.so.5 libnss_compat-2.33.so libnss_files-2.33.so libresolv-2.33.so libtinfo.so.5
$ ls ./x86_64-pokysdk-linux/usr/lib/
arm-poky-linux-gnueabi/ libdw-0.180.so libgio-2.0.so.0 liblzma.so.5.2.5 libpcre.so.1 libssl.so.1.1 libxml2.so.2
gio/ libdw.so.1 libgio-2.0.so.0.6400.5 liblzo2.so.2 libpcre.so.1.2.12 libstdc++.so.6 libxml2.so.2.9.10
libarchive.so.13 libelf-0.180.so libglib-2.0.so.0 liblzo2.so.2.0.0 libperl.so.5 libstdc++.so.6.0.28 libz.so.1
libarchive.so.13.4.3 libelf.so.1 libglib-2.0.so.0.6400.5 libmount.so.1 libperl.so.5.32.0 libtirpc.so.3 libz.so.1.2.11
libasm-0.180.so libexpat.so.1 libgmodule-2.0.so.0 libmount.so.1.1.0 libpixman-1.so.0 libtirpc.so.3.0.0 locale/
libasm.so.1 libexpat.so.1.6.11 libgmodule-2.0.so.0.6400.5 libmpc.so.3 libpixman-1.so.0.40.0 libuuid.so.1 perl5/
libblkid.so.1 libfdt.so.1 libgmp.so.10 libmpc.so.3.2.0 libpython3.8.so.1.0 libuuid.so.1.3.0 pseudo/
libblkid.so.1.1.0 libffi.so.7 libgmp.so.10.4.0 libmpfr.so.6 libreadline.so.8 libX11.so.6 python3.8/
libbz2.so.1 libffi.so.7.1.0 libgobject-2.0.so.0 libmpfr.so.6.1.0 libreadline.so.8.0 libX11.so.6.3.0 ssl-1.1/
libbz2.so.1.0.6 libfl.so.2 libgobject-2.0.so.0.6400.5 libnsl.so.2 libSDL2-2.0.so.0 libXau.so.6
libcrypto.so.1.1 libfl.so.2.0.0 libgthread-2.0.so.0 libnsl.so.2.0.1 libSDL2-2.0.so.0.12.0 libXau.so.6.0.0
libcrypt.so.2 libgdbm_compat.so.4 libgthread-2.0.so.0.6400.5 libopkg.so.1 libsolvext.so.1 libxcb.so.1
libcrypt.so.2.0.0 libgdbm_compat.so.4.0.0 libhistory.so.8 libopkg.so.1.0.0 libsolv.so.1 libxcb.so.1.1.0
libcurl.so.4 libgdbm.so.6 libhistory.so.8.0 libpanelw.so.5 libsqlite3.so.0 libXdmcp.so.6
libcurl.so.4.6.0 libgdbm.so.6.0.0 liblzma.so.5 libpanelw.so.5.9 libsqlite3.so.0.8.6 libXdmcp.so.6.0.0
这里面有交叉编译时使用的程序和库,比如arm-poky-linux-gnueabi-gcc程序。
另一个sysroot是我们目标板上的内容:
$ ls cortexa7t2hf-neon-poky-linux-gnueabi/usr/lib
acl libdl.so libicutest.so.67.1 libpanelw.so.5 libxcb-dri2.so
arm-poky-linux-gnueabi libdw-0.180.so libicutu.so libpanelw.so.5.9 libxcb-dri2.so.0
arm-poky-linux-gnueabihf libdw.so libicutu.so.67 libpango-1.0.so libxcb-dri2.so.0.0.0
audit libdw.so.1 libicutu.so.67.1 libpango-1.0.so.0 libxcb-dri3.so
cairo libelf-0.180.so libicuuc.so libpango-1.0.so.0.4600.2 libxcb-dri3.so.0
cmake libelf.so libicuuc.so.67 libpangocairo-1.0.so libxcb-dri3.so.0.0.0
crt1.o libelf.so.1 libicuuc.so.67.1 libpangocairo-1.0.so.0 libxcb-glx.so
crti.o libexpat.so libidn2.so libpangocairo-1.0.so.0.4600.2 libxcb-glx.so.0
crtn.o libexpat.so.1 libidn2.so.0 libpangoft2-1.0.so libxcb-glx.so.0.0.0
dbus-1.0 libexpat.so.1.6.11 libidn2.so.0.3.7 libpangoft2-1.0.so.0 libxcb-present.so
directfb-1.7-7 libfdisk.so libiio.so libpangoft2-1.0.so.0.4600.2 libxcb-present.so.0
e2fsprogs libffi.so libiio.so.0 libpangoxft-1.0.so libxcb-present.so.0.0.0
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
$ ls cortexa7t2hf-neon-poky-linux-gnueabi/usr/include/
acl cpio.h expat_external.h GL libaio.h misc nss.h sched.h tgmath.h urcu.h
aio.h crypt.h expat.h glib-2.0 libconfig.h mntent.h obstack.h scsi thread_db.h urcu-pointer.h
aliases.h ctype.h ext2fs glob.h libconfig.h++ monetary.h openssl search.h threads.h urcu-qsbr.h
alloca.h curses-32.h fcntl.h gmp-32.h libdaemon mosquitto_broker.h panel.h semaphore.h tic.h usbg
a.out.h cursesapp.h features.h gmp.h libelf.h mosquitto.h pango-1.0 setjmp.h time.h utarray.h
argp.h cursesf.h fenv.h gmpxx.h libfdisk mosquitto_plugin.h paths.h sgtty.h tirpc uthash.h
argz.h curses.h ffi-32.h gnu libgen.h mosquittopp.h pcrecpparg.h shadow.h ttyent.h utime.h
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
这是我们目标板上的库和头文件。
所以当我们编译一个运行在目标板上的程序时需要执行:
$ ./x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc -o app myapp.c --sysroot=/opt/poky-/EZ000259BAA/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi
提示找不到头文件: gnu/stubs-soft.h: No such file or directory,好像是和浮点运算有关。这个主控芯片用的是iMx6ULL,是硬件浮点,不是soft的,所以还缺一些mcu的配置参数如下:
$ ./x86_64-pokygen7sdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc main.c -o main --sysroot=/opt/poky-gen7/EZ000259BAA/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi/ -march=armv7ve -marm -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7
编译成功,不会出现某些库或头文件找不到的情况了。
参考:
How to Survive Embedded Linux: How to Compile - ByteSnap Design
https://www.bytesnap.com/news-blog/how-to-survive-embedded-linux-how-to-compile/Directory Options - Using the GNU Compiler Collection (GCC)
https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Directory-Options.htmlGCC floating-point options - SEGGER Wiki
https://wiki.segger.com/GCC_floating-point_options