Set*_*eth 7 linux gdb shared-libraries gdbserver
我在目标和CodeSourcery IDE上使用gdbserver.我的硬件是带有omap3530的gumstix.
我可以在主应用程序中单步执行代码,但如果我尝试进入共享库中的函数,则会获得内存地址并且调试器会终止.
这是我的库,它被编译并复制到目标系统上的/ lib文件夹.(它有调试符号)我试图使用.gbdinit文件来设置solib-absolute-prefix/lib
以下是gdb跟踪的警告:
903,056 13-gdb-set sysroot-on-target /lib
903,065 13^done
903,065 (gdb)
903,065 14-target-select remote 192.168.1.101:2345
903,114 =thread-group-started,id="i1",pid="42000"
903,114 =thread-created,id="1",group-id="i1"
903,115 15-list-thread-groups --available
903,120 16-list-thread-groups
903,128 &"warning: Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code."
903,128 &"\n"
Run Code Online (Sandbox Code Playgroud)
这导致
903,395 &"Error while mapping shared library sections:\n"
903,397 &"/lib/libCoreLib.so: Invalid argument.\n"
903,399 =library-loaded,id="/lib/libCoreLib.so",target-name="/lib/libCoreLib.so",hostname="/lib/libCoreLib.so",low-address="0x0",high-address="0x0",symbols-loaded="0",thread-group="i1"
Run Code Online (Sandbox Code Playgroud)
您可以使用安装在主机上的库进行调试,前提是调试机器也是开发机器。在这种情况下,您可以使用 set sysroot 而不是 set sysroot-on-target。例如 :
set sysroot /home/username/.../rootfs/
Run Code Online (Sandbox Code Playgroud)
where/home/username/.../rootfs/包含目标文件系统的副本
我认为你也应该指定/而不是/lib
带有调试符号的目标
这是最简单的开始工作方法,当您开发一个特定的共享库时它特别有用。
首先将测试可执行文件和共享库复制到带有调试信息的目标:
readelf ----debug-dump=decodedline libmyib.so:如何判断库是否是使用 -g 编译的?然后就达到了目标:
gdbserver --multi :1234 ./executable_name
Run Code Online (Sandbox Code Playgroud)
主持人:
arm-linux-gnueabihf-gdb -q -nh \
-ex "target extended-remote target-hostname-or-ip:1234" \
-ex "file ./executable_name" \
-ex 'tb main' \
-ex 'c' \
-ex 'set solib-search-path .'
Run Code Online (Sandbox Code Playgroud)
sharedlibrary libmylib.so也有效。
我遇到的问题是gdbserver在动态加载器之前停止,main并且此时动态库尚未加载,因此 GDB 还不知道符号将在内存中的位置。
GDB似乎有一些自动加载共享库符号的机制,如果我为主机编译并gdbserver在本地运行,main则不需要运行到。但在ARM目标上,这是最可靠的做法。
目标gdbserver7.12-6,主机arm-linux-gnueabihf-gdb来自 Linaro 的 7.6.1。
没有调试符号的目标库
在嵌入式目标上部署之前剥离目标库是很常见的,因为调试信息会使它们变得更大。
例如,Buildroot 默认情况下会执行此操作,但您可以使用 禁用它BR2_STRIP_none=y。
您可以通过运行以下命令来识别这种情况:
info shared
Run Code Online (Sandbox Code Playgroud)
这显示了类似的内容:
From To Syms Read Shared Object Library
0x00007ffff7df7f90 0x00007ffff7dfcdd7 Yes (*) target:/lib/ld64-uClibc.so.0
0x00007ffff7b3a9b0 0x00007ffff7bbe05d Yes (*) target:/lib/libc.so.0
(*): Shared library is missing debugging information.
Run Code Online (Sandbox Code Playgroud)
因此这两个库都有星号 ( *),表示缺少调试信息。
如果是这种情况,那么您必须在主机上的共享库被剥离之前告诉 GDB 使用它们。
例如,Buildroot 使这对我们来说很容易,因为它在staging删除共享库之前维护包含共享库的目录,并且其相对路径与目标中的相对路径相同:
set sysroot buildroot/output/staging/
Run Code Online (Sandbox Code Playgroud)
设置此选项后,gdb立即在主机而不是目标中搜索库,并/lib/libc.so.0在路径buildroot/output/staging/+处查找/lib/libc.so.0:
Reading symbols from buildroot/output/staging/lib/ld64-uClibc.so.0...done.
Reading symbols from buildroot/output/staging/lib/libc.so.0...done.
Run Code Online (Sandbox Code Playgroud)
TODO:我认为您不能设置多个sysroot,因此所有共享库必须放置在目标图像中正确的相对路径中。
如果您检查错误的默认 sysroot,您将看到:
show sysroot
Run Code Online (Sandbox Code Playgroud)
给:
target:
Run Code Online (Sandbox Code Playgroud)
这意味着默认gdb在目标根目录上搜索共享库。/
| 归档时间: |
|
| 查看次数: |
11959 次 |
| 最近记录: |