gdb调试arm:gdb-multiarch gdbserver coredump

ARM - PC 通过网络进行arm的gdb调试

碎念,gdb调试arm花去了断断续续几天的时间,网上虽然有很多文章,但都是基于一个英文文章翻译的,我按那篇文章操作,一直不成功,索性自己一点点试,终于试出点眉目

提示几个问题点

  1. 配置PC端的gdb的几个环境变量,这些环境变量的路径是PC的路径,我们要准备rootfs在PC上。这问问题很多文章里写了,但是没有强调,搞的人不知道环境变量路径是对应的PC的路径还是ARM的路径。
  2. 配置环境变量了,但是又配置的不够充分,有些库找不到。
  3. 找到了库,在调试过程中还会有调试到库的时候,没有debug信息,库没有debug信息会打印问号,这时我们是否需要进行处理。

前提假设

  1. PC系统是ubuntu,ip是192.168.2.202
  2. ARM系统是linux,ip是192.168.2.200
  3. ARM上安装了在PC上交叉编译的gdbserver,PC上安装了gdb-multiarch命令
  4. PC上保存有和ARM上同样的rootfs,PC上rootfs保存在本机 /home/tronlong目录下,名字为/home/tronlong/rootfs
  5. 待调试的程序名为kzx-xdl是在PC上交叉编译后的程序,gcc / g++ 编译时使用了-g选项

arm上执行

gdbserver 192.168.2.202:1234 ./kzx-xdl

ubuntu上执行

gdb-multiarch ./kzx-xdl     (可用sudo 也 可不用sudo)
 (gdb) set architecture arm
 (gdb) set sysroot /home/tronlong/rootfs
 (gdb) set solib-search-path /home/tronlong/ti-processor-sdk-linux-rt-am57xx-evm-04.03.00.05/linux-devkit/sysroots/x86_64-arago-linux/usr/lib:/home/tronlong/rootfs/lib
 去除交叉编译工具链的库路径,改为:
 (gdb) set solib-search-path /home/tronlong/rootfs/lib:/home/tronlong/rootfs/usr/lib
 (gdb) set solib-absolute-prefix /home/tronlong/rootfs
 (gdb) target remote 192.168.2.200:1234

在配置正常时,PC通过网络连上ARM之后,在ubuntu上执行continue.

(gdb) continue
Continuing.

程序中printf的输出从gdbserver那边输出

解释

/home/tronlong/ti-processor-sdk-linux-rt-am57xx-evm-04.03.00.05/linux-devkit/sysroots/x86_64-arago-linux/usr/lib 为PC上ARM交叉编译工具链的的库路径,网上有人把这个路径也加到 solib-search-path 内了,加不加主要看你的程序里会不会引用对应的库。

我遇到问题的过程先表述一下

假设当前PC端未设置gdb环境变量,gdb会出现找不到库的情况

PC端gdb-multiarch调试时显示:

(gdb) 
...... 省略
warning: Could not load shared library symbols for /usr/lib/libts-1.0.so.0.
Do you need "set solib-search-path" or "set sysroot"?
...... 省略
0xb6fd79c0 in ?? ()
...... 省略

ARM上搜libts-1.0.so.0

root@AM57xx-Tronlong:/mnt/nfs# ls -al /usr/lib |grep libts-1.0.so.0
lrwxrwxrwx    1 root     root            18 Oct 14 20:26 libts-1.0.so.0 -> libts-1.0.so.0.0.0
-rwxr-xr-x    1 root     root          7112 Oct 14 20:26 libts-1.0.so.0.0.0

然后添加环境变量,再重新走一遍流程,还是上面的问题,搞了很久才明白,是未添加环境变量的原因,那么就在gdb调试时添加

(gdb)
set solib-search-path /home/tronlong/rootfs/lib:/home/tronlong/rootfs/usr/lib

结果还是不行

PC上搜libts-1.0.so.0

tronlong@tronlong-virtual-machine:~/rootfs/usr/lib$ ls -al |grep libts-1.0.so.0
tronlong@tronlong-virtual-machine:~/rootfs/usr/lib$

PC的/home/tronlong/rootfs底下缺东西,说明PC上的rootfs与设备端的rootfs不一致(实际情况是,的确是不一致)

做驱动的同事给了我新的rootfs(他说这个rootfs和设备的一样),我把它依然放在了ubuntu的/home/tronlong/rootfs目录下(替换之前的rootfs),然后就可以了。

(gdb) target remote 192.168.2.200:1234
Remote debugging using 192.168.2.200:1234
warning: limiting remote suggested packet size (18431 bytes) to 16384
Reading symbols from /home/tronlong/rootfs/lib/ld-linux-armhf.so.3...(no debugging symbols found)...done.
Loaded symbols for /home/tronlong/rootfs/lib/ld-linux-armhf.so.3
Cannot access memory at address 0x0
0xb6fd79c0 in ?? () from /home/tronlong/rootfs/lib/ld-linux-armhf.so.3

但看PC端gdb-multiarch的输出,还是有问号的问题,这时不时找不到库了,而是库没有debug的符号表。
网友回答:

仔细看no debugging symbols found是在哪里的。是载入系统lib库的时候没有调试符号,这当然是没有的。

那么我不用理他,继续运行其他命令,调用list命令,bingo,终于看到代码了。

(gdb) list
9	Txdl myxdl;
10	effectivevaluethread rms;
11	algorithmthread algorithm;
12	comtradethread comtrade;
13	CANrec direc;
14	
15	int main(int argc, char *argv[])
16	{
17	    //调用虚拟键盘
18	    qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));

coredump处理

在发生coredump时,把coredump文件从arm拷到ubuntu。
ubuntu# gdb-multiarch ./kzx-xdl ./core.QThread.998.1603867475
(无需arm端执行,gdbserver)

(gdb) bt

在arm上执行kzx-xdl时不保存coredump文件时如何配置的问题。
arm 的/etc/sysctl.conf文件后面添加一行
kernel.core_pattern=/corefile/core.%e.%p.%t
其中/corefile目录可以根据情况自行更改,没有/corefile这个路径时需要先创建此目录。

例子:解决一个coredump问题,原因是kzx-xdl程序的comtrade进程内访问的文件不存在,所以逻辑出现了错误,引发的coredump

tronlong@zhangjyvm:~/nfs_share/work$ sudo gdb-multiarch ./kzx-xdl ./core.comtrade.1171.6
...... 省略了很多上面配置路径的语句和打印的语句
(gdb) bt
#0  0xb5e18ab6 in ?? () from /home/tronlong/rootfs/lib/libc.so.6
#1  0xb5e264f0 in raise () from /home/tronlong/rootfs/lib/libc.so.6
#2  0xb5e271ea in abort () from /home/tronlong/rootfs/lib/libc.so.6
#3  0xb61bdfa0 in QMessageLogger::fatal(char const*, ...) const () from /home/tronlong/rootfs/usr/lib/libQt5Core.so.5
#4  0xb61b94f8 in qt_assert_x(char const*, char const*, char const*, int) () from /home/tronlong/rootfs/usr/lib/libQt5Core.so.5
#5  0x000e81f0 in QList<QString>::operator[] (this=0xb01fece8, i=1)
    at ../../ti-processor-sdk-linux-rt-am57xx-evm-04.03.00.05/linux-devkit/sysroots/armv7ahf-neon-linux-gnueabi/usr/include/qt5/QtCore/qlist.h:545
#6  0x000eee50 in comtradethread::xdl_initComtradeCfg (this=0x10a384f8 <comtrade>) at ../kzx-xdl/extensivecalc.cpp:620
#7  0x000eebb0 in comtradethread::StartWaveRecord (this=0x10a384f8 <comtrade>) at ../kzx-xdl/extensivecalc.cpp:597
#8  0x000eeb58 in comtradethread::run (this=0x10a384f8 <comtrade>) at ../kzx-xdl/extensivecalc.cpp:588
#9  0xb61d7734 in ?? () from /home/tronlong/rootfs/usr/lib/libQt5Core.so.5
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) 

coredump产生后,进程内所有的线程都退出了,这点需要注意,架构设计时要考虑这个问题。

bt命令后的 #0 - #9行是这样的:
线程comtrade的coredump产生时,此线程的栈从#0 - #9层层保存,

  1. libc.so.6内的??(未知函数)-> libc.so.6内的函数raise()-> libc.so.6内的函数abort()->
  2. libQt5Core.so.5内的函数QMessageLogger::fatal(char const*, …) const ->
  3. libQt5Core.so.5内的函数qt_assert_x(char const*, char const*, char const*, int) ()->
  4. extensivecalc.cpp:620行,函数comtradethread::xdl_initComtradeCfg->
  5. extensivecalc.cpp:597行,函数comtradethread::StartWaveRecord->
  6. extensivecalc.cpp:588行,函数comtradethread::run 退出到这里已经到了线程超级循环函数了。
编译 `arm-linux-gnueabih-gdb` 和 `arm-linux-gnueabih-gdbserver` 的步骤如下: 1. 下载 GNU 工具链 - 从官网下载源代码:https://ftp.gnu.org/gnu/binutils/binutils-2.36.tar.gz - 解压缩源代码:`tar -zxvf binutils-2.36.tar.gz` 2. 配置交叉编译环境变量 - `export CC=arm-linux-gnueabihf-gcc` - `export CXX=arm-linux-gnueabihf-g++` - `export AR=arm-linux-gnueabihf-ar` - `export AS=arm-linux-gnueabihf-as` - `export LD=arm-linux-gnueabihf-ld` - `export RANLIB=arm-linux-gnueabihf-ranlib` 3. 配置和编译 `binutils` - 进入源代码目录:`cd binutils-2.36` - 创建编译目录:`mkdir build && cd build` - 配置交叉编译环境:`../configure --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf --prefix=/usr/local/arm-linux-gnueabihf` - 编译:`make` - 安装:`make install` 4. 配置和编译 `gdb` - 下载 GDB 源代码:https://ftp.gnu.org/gnu/gdb/gdb-10.1.tar.gz - 解压缩源代码:`tar -zxvf gdb-10.1.tar.gz` - 进入源代码目录:`cd gdb-10.1` - 创建编译目录:`mkdir build && cd build` - 配置交叉编译环境:`../configure --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf --prefix=/usr/local/arm-linux-gnueabihf` - 编译:`make` - 安装:`make install` 5. 配置和编译 `gdbserver` - 下载 GDB 源代码:https://ftp.gnu.org/gnu/gdb/gdb-10.1.tar.gz - 解压缩源代码:`tar -zxvf gdb-10.1.tar.gz` - 进入源代码目录:`cd gdb-10.1/gdb/gdbserver` - 创建编译目录:`mkdir build && cd build` - 配置交叉编译环境:`export CC=arm-linux-gnueabihf-gcc` - 配置编译选项:`../configure --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf --prefix=/usr/local/arm-linux-gnueabihf` - 编译:`make` - 安装:`make install` 注意:以上步骤仅供参考,实际操作时可能会因为环境和版本差异而有所不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值