一种从本地sysroot和远程gdbserver获得GDB加载库的方法 [英] A way to have GDB load libraries from local sysroot and remote gdbserver

查看:900
本文介绍了一种从本地sysroot和远程gdbserver获得GDB加载库的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用gdbserver进行远程调试时,我想让gdb从本地sysroot加载正在调试的程序的某些共享库,但也允许从gdbserver进行下载以加载sysroot中不存在的其他功能。

When remote debugging using gdbserver, I'd like to get gdb to load some shared libraries of the programm being debugging from the local sysroot, but also allow download feature from gdbserver to load others, which are not present in the sysroot.

似乎gdb只能使用一种方法来查找库,本地文件或远程下载,而不能同时使用两种方法。

It seems that gdb can use only one method to find libraries, local files or remote download, and not both.

例如,如果我将sysroot设置为 target:/ 以使用远程文件,则将下载所有内容:

Example, if I set sysroot to target:/ to use remote files, everything will be downloaded:

(gdb) set sysroot target:/
(gdb) run
Starting program:  
Reading /root/a.out from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /root/a.out from remote target...
Reading symbols from target:/root/a.out...
Reading /lib/ld-linux-armhf.so.3 from remote target...

不幸的是,远程系统上的系统库没有调试符号。这是具有有限闪存空间的嵌入式系统。调试符号会大大增加文件系统的总大小,根本不适合使用。

Unfortunately, the system libraries on the remote system do not have debug symbols. It's an embedded system with limited flash space. Debugging symbols increase the total file system size a great deal and simply don't fit.

但是,我有一个包含所有系统库的本地sysroot树,这确实包括调试符号。但是,如果我将sysroot设置为该树,则gdb将不再考虑远程下载。

However, I have a local sysroot tree of all the system libraries and this does include debugging symbols. But if I set sysroot to this tree, gdb will no longer consider remote downloads.

(gdb) set sysroot /bsp/sysroot
(gdb) run
Starting program:  
Reading symbols from /bsp/sysroot/root/a.out...
warning: Could not load shared library symbols for /lib/libm.so.6.

在此示例中,sysroot中不存在libm.so.6,但可以将其下载从目标。但是现在似乎有办法将 target:/ 添加回搜索路径。将其放入solib-search-path无效。

In this example, libm.so.6 is not present in the sysroot, but could have been downloaded from the target. But there seems to be now way to add target:/ back to the search path. Putting it in solib-search-path has no effect.

这种情况是由于嵌入式系统开发中使用了板级支持包(BSP)引起的。 BSP包含许多库,这些库在目标上已剥离,否则它们将无法容纳,但为主机提供了未剥离的副本。 BSP的用户可以构建自己的软件,但是该软件不是BSP的一部分,也不存在于BSP的sysroot中。

This situation arises from the use of a board support package (BSP) in embedded systems development. The BSP contains many libraries, which are stripped on the target, as they wouldn't fit otherwise, but have unstripped copies for the host. Users of the BSP build their own software it, but this software isn't part of the BSP and isn't present in the BSP's sysroot. It is however on the target system.

似乎没有办法告诉gdb首先尝试在本地查找库,但是如果找不到它们,便退回远程下载。

There seems no way to tell gdb to first try to find libraries locally, but then fall back to remote download if they are not found.

推荐答案

GDB不支持多个sysroot,但是有一些解决方法。

GDB does not support multiple sysroots, but there are some work-arounds.


  • 解决此问题的一种方法是修补GDB以实际支持多个sysroot。 gdb / solib.c 中的函数 solib_find_1 sysroot (如果以 target:开头,则使用目标中的库)。否则,它将使用基本名称(即,从给定的绝对路径中获取文件名),并在 solib-search-path

    要获得所需的行为,请使用 solib_find_1 函数应改回其他目录,例如此补丁: https://gitlab.com/gbenson/binutils-gdb/commit/0ebe17076406a85a85eb850

  • 一种不修补GDB的简单方法:将目标库复制到主机。变体包括:


    • 直接在本地sysroot内部。这是快速而简单的。

    • 通过本地sysroot内部的符号链接指向目标库的位置。

    • 使用合并多个位置的文件系统,例如 OverlayFS

    • 使用绑定挂载,以通过sysroot挂载目录或文件。

    • One way to fix the issue is by patching GDB to actually support multiple sysroots. Function solib_find_1 in gdb/solib.c (link to source code) handles the library lookup. Currently, it checks the sysroot (and if that starts with target:, uses the libraries from the target). Otherwise it takes the basename (i.e. takes the file name from the given absolute path) and looks up the libraries in solib-search-path.
      To get the desired behavior, the solib_find_1 function should instead fall back to a different directory, e.g. this patch: https://gitlab.com/gbenson/binutils-gdb/commit/0ebe17076406a85a35eb0c4f362850ed9efb843e
    • A simpler approach without patching GDB: Copy the target libraries to the host. Variants include:
      • Directly inside the local sysroot. This is quick and simple.
      • With symlinks inside the local sysroot to the location of the target libraries.
      • Use a filesystem that merges multiple locations, such as OverlayFS.
      • Use a bind mount to mount the directories or files over the sysroot.

      1. 使用设置sysroot目标:

      2. 创建 GDB的文件I / O远程协议,并使其透明转发所有消息,但对目标文件的请求除外。如果感兴趣的文件在本地可用,请回复。否则,按原样转发消息。

      3. 使用 target remote:[your_proxy_port] 代替来连接调试器目标远程:[actual_gdbserver_port] ,以使您的代理代表您连接到gdbserver。

      1. Use set sysroot target:
      2. Create a proxy for GDB's File-I/O Remote Protocol, and let it transparently forward every message, except for requests for target files. If the files of interest are available locally, reply with that. Otherwise forward the message as-is.
      3. Attach the debugger using target remote :[your_proxy_port] instead of target remote :[actual_gdbserver_port], to let your proxy connect to the gdbserver on your behalf.


    • 我发现结合使用将目标库复制到主机变体是最有效的,因为它具有最低要求(我只需要一种从以下位置复制/接收文件的方法目标一次):

      I found that a combination of the "Copy the target libraries to the host" variants was the most effective, as it has minimal requirements (I only need a way to copy/receive files from the target once):


      • 我将系统库从目标复制到了本地目录。实际上,我复制了所有这些文件,因此不必找出我真正需要的文件。

      • 我在应用程序目标上重新创建了目录结构,并在构建中添加了符号链接我项目的输出目录。使用symlinks可以使设置正常运行而无需重复维护。

      sysroot的内容实际上不必相同到目标的远程文件:目标已剥离了没有调试符号的库,而我在sysroot中使用了非剥离的库。

      The content of the sysroot didn't actually have to be identical to the target's remote files: The target had stripped libraries without debugging symbols, while I used the non-stripped libraries in the sysroot.

      这篇关于一种从本地sysroot和远程gdbserver获得GDB加载库的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆