使用 gdbserver 调试共享库
我在目标和 CodeSourcery IDE 上使用 gdbserver。我的硬件是带有 omap3530 的牙龈。
我可以单步执行主应用程序中的代码,但如果我尝试单步执行共享库中的函数,我会获得内存地址,并且调试器会终止。
这是我的库,已编译并复制到目标系统上的 /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"
I am using gdbserver on target and CodeSourcery IDE. My hardware is a gumstix with a omap3530.
I can step through code in my main application but if I attempt to step into a function in a shared library I get memory address and a debugger terminates.
This is my library that is compiled and copied to the /lib folder on the target system.(it does have debug symbols) I have attempted to use the .gbdinit file to set solib-absolute-prefix /lib
Here are the warnings from the gdb trace:
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"
Which leads to
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"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以使用主机上安装的库进行调试,前提是调试机器也是开发机器。在这种情况下,您可以使用 set sysroot 而不是 set sysroot-on-target。例如:
其中
/home/username/.../rootfs/
包含目标文件系统的副本我认为您还应该指定
/
而不是/lib
You can debug with the library installed on your host, provided the debugging machine is also the development machine. In that case, you use set sysroot instead of set sysroot-on-target. For example :
where
/home/username/.../rootfs/
contains a copy of your target filesystemI think you should also specify
/
instead of/lib
使用调试符号作为目标
这是最简单的工作方法,当您开发一个特定的共享库时它特别有用。
首先将测试可执行文件和共享库复制到目标和调试信息:
readelf ----debug-dump=decodedline libmyib.so
进行检查:如何判断库是否是使用 -g 编译的?然后在目标上:
主机:
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
禁用它。您可以通过运行来识别这种情况:
它显示如下内容:
因此两个库都有星号 (
*
),表示缺少调试信息。如果是这种情况,那么您必须在主机上的共享库被删除之前告诉 GDB 使用它们。
例如,Buildroot 让这对我们来说很容易,因为它维护了
staging
目录,其中包含被剥离之前的共享库,并且位于与目标中相同的相对路径中:设置此选项时,
gdb
立即在主机而不是目标中搜索库,并在路径buildroot/output/staging/
处找到/lib/libc.so.0
+/lib/libc.so.0
:TODO:我认为您不能设置多个
sysroot
,因此所有共享库必须放置在其正确的相对目录中路径与目标图像中相同。如果您检查错误的默认 sysroot,您将看到:
Give:
这意味着
gdb
默认在目标根/
上搜索共享库。Target with debug symbols
This is the simplest method to get working, and it is specially useful when you are developing one particular shared library.
First copy the test executable and shared library to the target with debug information:
readelf ----debug-dump=decodedline libmyib.so
: How can I tell if a library was compiled with -g?Then on target:
Host:
sharedlibrary libmylib.so
also works.The problem I had was that
gdbserver
stops at the dynamic loader, beforemain
, and the dynamic libraries are not yet loaded at that point, and so GDB does not know where the symbols will go in memory yet.GDB appears to have some mechanisms to automatically load shared library symbols, and if I compile for host, and run
gdbserver
locally, running tomain
is not needed. But on the ARM target, that is the most reliable thing to do.Target
gdbserver
7.12-6, hostarm-linux-gnueabihf-gdb
7.6.1 from Linaro.Target libraries without debug symbols
It is common to strip target libraries before deployment on embedded targets, since debug information makes them way larger.
For example, Buildroot does that by default, but you can disable it with
BR2_STRIP_none=y
.You can identify this scenario by running:
Which shows something like:
so there are asterisks (
*
) for both of the libraries which says that debug information is missing.If that is the case, then you have to tell GDB to use the shared libraries on host before they were stripped.
Buildroot for example makes that easy for us, as it maintains the
staging
directory which contains the shared libraries before they were stripped and in the same relative paths as in the target:When this option is set,
gdb
immediately searches for libraries in the host instead of target, and finds/lib/libc.so.0
at the pathbuildroot/output/staging/
+/lib/libc.so.0
:TODO: I don't think you can set more than one
sysroot
, so all your shared libraries must be placed in their correct relative paths as in the target image.If you check the bad default sysroot, you will see:
give:
which means that
gdb
searches for shared libraries on the target root/
by default.调试时也遇到类似问题。调试挂了。配置如下
Host:Ubuntu 12.04LTS
IDE:Eclipse Kepler
Target:Beaglebone Black / ARM A8
OS: Angstrom
解决方案
更新库并包含
在 Eclipse 中选择项目属性
C/C++ 常规 >路径和符号> (包括TAB) GNU C >添加>文件
系统> //> usr 从 /usr/lib/gcc/i686-linux-gnu/4/6/include 更改
到 /usr/arm-linux-gnueabi/include
C/C++ 常规 >路径和符号> (包括TAB) GNU C++>添加>
文件系统> //> usr /usr/arm-linux-gnueabi/include/c++/4.6.3/arm-linux-gnueabi
C/C++ 常规 >路径和符号> (库路径选项卡)>添加>文件
系统> //> usr /usr/arm-linux-gnueabi/lib
Similar issue was encountered while debugging. The debug was hanging up. Configuration is as follows
Host: Ubuntu 12.04LTS
IDE: Eclipse Kepler
Target: Beaglebone Black / ARM A8
OS: Angstrom
Solution
Update libraries and includes
Select properties for project in Eclipse
C/C++ General > Paths and Symbols > (include TAB) GNU C > Add > Files
systems > / > usr Change from /usr/lib/gcc/i686-linux-gnu/4/6/include
to /usr/arm-linux-gnueabi/include
C/C++ General > Paths and Symbols > (Include TAB) GNU C++> Add >
Files systems > / > usr /usr/arm-linux-gnueabi/include/c++/4.6.3/arm-linux-gnueabi
C/C++ General > Paths and Symbols > (Library Paths TAB) > Add > Files
systems > / > usr /usr/arm-linux-gnueabi/lib
美好的一天,
如果 GDB 中的“debug-file-directory”变量设置不正确,
那么报告的错误信息包含:
警告:无法找到动态链接器断点函数。
目标的根文件系统位于我的主机上
/opt/arm-linux-gnueabihf-rootfs
以下两个命令帮助我进行远程调试
通过 gdbserver 使用 GDB (v7.11.1):
我注意到如果“sysroot”在路径中有一个尾部斜杠,
那么 GDB 无法使用它。连接到远程目标后,您将看到以下内容(不正确的输出):
或者
不是正确的输出:
问候,
弗里基·蒂里昂
Good day,
If the 'debug-file-directory' variable in GDB is set incorrectly,
then the reported error messages contains:
warning: Unable to find dynamic linker breakpoint function.
The root filesystem of the target is located on my host PC at
/opt/arm-linux-gnueabihf-rootfs
The following two commands helped me to get remote debugging working
via gdbserver using GDB (v7.11.1):
I've noticed that if 'sysroot' has a trailing slash in the path,
then GDB fails to use it.You will see this (incorrect output) after connecting to the remote target:
or
instead of the correct output:
Regards,
Frikkie Thirion