我在目标和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"
导致
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"
答案 0 :(得分:4)
如果调试机器也是开发机器,您可以使用主机上安装的库进行调试。在这种情况下,您使用set sysroot而不是set sysroot-on-target。例如:
set sysroot /home/username/.../rootfs/
其中/home/username/.../rootfs/
包含目标文件系统的副本
我认为您还应该指定/
而不是/lib
答案 1 :(得分:1)
使用调试符号进行定位
这是最简单的工作方法,在开发一个特定的共享库时它特别有用。
首先使用调试信息将测试可执行文件和共享库复制到目标:
readelf ----debug-dump=decodedline libmyib.so
:How can I tell if a library was compiled with -g? 然后在目标上:
gdbserver --multi :1234 ./executable_name
主机:
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 .'
sharedlibrary libmylib.so
也有效。
我遇到的问题是gdbserver
在main
之前停止在动态加载器处,并且此时尚未加载动态库,因此GDB不知道符号将在何处在记忆中。
GDB似乎有一些自动加载共享库符号的机制,如果我为主机编译,并在本地运行gdbserver
,则不需要运行到main
。但是在ARM目标上,这是最可靠的事情。
目标gdbserver
7.12-6,来自Linaro的主持人arm-linux-gnueabihf-gdb
7.6.1。
没有调试符号的目标库
在嵌入式目标上部署之前剥离目标库是很常见的,因为调试信息使它们方式更大。
例如,Buildroot默认执行此操作,但您可以使用BR2_STRIP_none=y
禁用它。
您可以通过运行以下来识别此方案:
info shared
其中显示的内容如下:
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.
因此两个库都有星号(*
),表示缺少调试信息。
如果是这种情况,那么你必须告诉GDB在它们被删除之前使用主机上的共享库。
例如, Buildroot让我们很容易,因为它在被剥离之前维护包含共享库的staging
目录,并且与目标中的相对路径相同:
set sysroot buildroot/output/staging/
设置此选项后,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.
TODO:我认为你不能设置多个sysroot
,因此所有共享库必须放在正确的相对路径中,就像在目标图像中一样。
如果检查错误的默认sysroot,您将看到:
show sysroot
得到:
target:
这意味着默认情况下gdb
会在目标根/
上搜索共享库。
答案 2 :(得分:0)
调试时遇到类似问题。调试挂了。配置如下
主机:Ubuntu 12.04LTS
IDE :Eclipse Kepler
目标:Beaglebone Black / ARM A8
操作系统:Angstrom
<强>解决方案强>
更新库并包含
在Eclipse中选择项目的属性
C / C ++ General&gt;路径和符号&gt; (包括TAB)GNU C&gt;添加&gt;档 系统&gt; /&gt; usr从/ usr / lib / gcc / i686-linux-gnu / 4/6 / include更改 到/ usr / arm-linux-gnueabi / include
C / C ++ General&gt;路径和符号&gt; (包括TAB)GNU C ++&gt;添加&gt;
文件系统&gt; /&gt; usr / usr / arm-linux-gnueabi / include / c ++ / 4.6.3 / arm-linux-gnueabi
C / C ++ General&gt;路径和符号&gt; (库路径TAB)&gt;添加&gt;档 系统&gt; /&gt; usr / usr / arm-linux-gnueabi / lib
答案 3 :(得分:0)
美好的一天,
如果GDB中的'debug-file-directory'变量设置不正确, 然后报告的错误消息包含: 警告:无法找到动态链接器断点函数。
目标的根文件系统位于我的主机PC上 的/ opt /臂-Linux的gnueabihf-rootfs的
以下两个命令帮助我实现远程调试 通过gdbserver使用GDB(v7.11.1):
set debug-file-directory /opt/arm-linux-gnueabihf-rootfs/usr/lib/debug
set sysroot /opt/arm-linux-gnueabihf-rootfs
我注意到如果'sysroot'在路径中有一个尾部斜杠, 然后GDB无法使用它。在连接到远程目标后,你会看到这个(输出不正确):
Reading /lib/ld-linux-armhf.so.3 from remote target...
或
Reading symbols from /opt/arm-linux-gnueabihf-rootfs/lib/ld-linux-
armhf.so.3...(no debugging symbols found)...done
而不是正确的输出:
Reading symbols from /opt/arm-linux-gnueabihf-rootfs/lib/ld-linux-
armhf.so.3...
Reading symbols from /opt/arm-linux-gnueabihf-rootfs/usr/lib/debug/
lib/arm-linux-gnueabihf/ld-2.23.so...done.
此致 Frikkie Thirion