gnu ld/gdb:单独的调试文件。当有太多调试信息需要链接时如何生成调试文件?

2023-12-22

现在有gdb and binutils支持将调试信息与要调试的二进制文件分开。描述这一点的文档可以在以下位置找到:

  • gdb:单独的调试文件 http://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
  • objcopy --add-gnu-debuglink, --only-keep-debug http://sourceware.org/binutils/docs-2.23.1/binutils/objcopy.html#objcopy
  • ld --构建 ID http://sourceware.org/binutils/docs/ld/Options.html#Options

经过一番实验后,我能够得到gdb(7.6) 使用 build-id 和 debug-link 方法查找调试信息。这里有两个gdb显示调试器分别使用 build-id 和 debug-link 方法在非标准位置查找调试信息的片段:

(gdb)  set debug-file-directory .
(gdb) file uWithBuildId
Reading symbols from /home/peeterj/build-id/uWithBuildId...Reading symbols from /home/peeterj/build-id/.build-id/2d/41caac1bcbeb65255abc3f35624cf9ed37791a.debug...done.


Reading symbols from /home/peeterj/build-id/uWithDebugLink...Reading symbols from /home/peeterj/build-id/uWithDebugLink.debug...done.

创建我使用过的调试信息文件objcopy and strip。我在下面提供了此类命令的详细信息以供参考。

然而,我之所以关注这个,是希望能够构建all我们的产品代码-g。目前,如果我们尝试的话,这会破坏调试器,因为我们的共享库太大,重定位被截断以适应如下消息:

/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o:(.debug_aranges+0x6):     relocation truncated to fit: R_X86_64_32 against `.debug_info'

(以及随后的链接失败)

有谁知道一种方法可以做到以下之一:

  1. 生成一个独立文件,其中包含来自对二进制文件有贡献的源的所有调试信息(即最终出现在ld生成二进制文件的命令)。
  2. 或者,指示ld链接而不在二进制文件本身中包含此调试信息,并生成可以使用 build-id 或调试链接标识的独立调试文件?我在文档中没有看到任何用于执行此操作的单遍方法的内容ld,但是ld文档很大,也许我错过了。
  3. 处理上面截断错误的某种方法(这样的方法将允许 build-id 或 debug-link 方法工作)。

为可执行文件生成单独的调试文件的示例命令

这是使用以下命令的示例命令行序列--build-id and --add-gnu-debuglink方法:

g++ -g   -c -o u.o u.cpp
g++ -o uWithBuildId -Wl,--build-id u.o
g++ -o uWithDebugLink u.o
copyDebugAndStrip uWithBuildId
objcopy --only-keep-debug uWithDebugLink uWithDebugLink.debug
objcopy --add-gnu-debuglink=uWithDebugLink.debug uWithDebugLink
strip -g uWithDebugLink

其中 copyDebugAndStrip 是以下 Perl 代码:

#!/usr/bin/perl

my $binary = $ARGV[0] ;
my @p = `objdump --section .note.gnu.build-id -s $binary | tail -2` ;
foreach (@p)
{
   chomp ;
   s/^ *[\da-f]+ *// ;
   s/  .*// ;
   s/ //g ;
}

my $buildid = "$p[0]$p[1]" ;
$buildid =~ /^(..)(.*)/ ;

my ($d, $r) = ($1, $2) ;

print "build-id for '$binary': $buildid\n" ;

my $cmd =
"mkdir -p .build-id/$d
rm -f .build-id/$d/$r.debug
objcopy --only-keep-debug $binary .build-id/$d/$r.debug
strip -g $binary
" ;

print $cmd ;
system $cmd ;

最初似乎是binutilsgold 链接器能够构建大型 -g 共享库,为上述 (3) 提供了解决方案,但事实证明这是因为缺乏错误检查。

另一方面,如果使用尖端工具链,则 (1) 和 (2) 上的工作似乎是可用的,这是裂变 dwarf/binutils/gcc 工作的一部分,如下所述:

  • http://gcc.gnu.org/ml/gcc/2011-10/msg00326.html http://gcc.gnu.org/ml/gcc/2011-10/msg00326.html
  • http://gcc.gnu.org/wiki/DebugFission http://gcc.gnu.org/wiki/DebugFission

在关于此重定位截断错误的 bugzilla 报告的讨论中提到了这项裂变工作:

http://sourceware.org/bugzilla/show_bug.cgi?id=15444 http://sourceware.org/bugzilla/show_bug.cgi?id=15444

使用此分割调试文件的示例是:

g++ -gsplit-dwarf -gdwarf-4   -c -o main.o main.cpp
gcc -gsplit-dwarf -gdwarf-4   -c -o d1/t1.o d1/t1.c
g++ -gsplit-dwarf -gdwarf-4   -c -o d2/t2.o d2/t2.cpp
gcc -Wl,--index-gdb main.o d1/t1.o d2/t2.o   -o main

where gcc/g++是版本 4.8,binutils trunk (cvs -z 9 -d :pserver:[email protected] /cdn-cgi/l/email-protection:/cvs/src co binutils)已使用配置--enable-gold=default,最后使用gdb 7.6版本,它可以读取分割调试信息。

加入 gcc 行列,intel(版本 16)编译器支持 -gsplit-dwarf。英特尔编译器记录需要 binutils-2.24+、gdb-7.6.1+。 clang 编译器代码库有一些 split dwarf 支持,但我不知道该支持处于什么状态。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gnu ld/gdb:单独的调试文件。当有太多调试信息需要链接时如何生成调试文件? 的相关文章

  • 调试时的监视窗口:CS0103:当前上下文中不存在名称“

    我正在使用 Visual Studio Community 2022 64 bit Version 17 4 2 with NET Framework Version 4 8 09032 昨天 2022 年 2 月 12 日有更新 我是通过
  • Android 中什么原因导致 MotionEvent.ACTION_CANCEL?

    我正在调试 Android 上的一些触摸处理内容 并试图找出为什么 MotionEvent 发送到我的视图onTouchListener包含一个cancel行动 我无法找到任何有关其原因的文档 并且希望有人能为我指出调试此问题的正确方向 错
  • dprintf 与 break + 命令 + continue 之间有什么区别?

    例如 dprintf main hello n run 生成与以下内容相同的输出 break main commands silent printf hello n continue end run 使用是否有显着的优势dprintf ov
  • 如何显示由 setTimeout/setInterval 生成的每个正在运行的线程的列表

    我想通过纯 javascript 或浏览器中的任何类型的控制台或其他方式来完成此操作 是否可以 Thanks 进一步说明 我想调试一个执行动画的库 我想知道如果有多个对象被动画化 是否会创建多个计时器 注意setTimeout 不会产生新线
  • 当私有成员变量更改值时,如何停止 Visual Studio 调试器中的执行?

    假设我的类有一个名为 count 的私有整数变量 我已经在代码中遇到了断点 现在 在我按 继续 之前 我想让调试器在 count 获得分配给它的新值时停止 除了将 count 提升到字段并在字段的 set 方法上设置断点之外 还有其他方法吗
  • 调试Windows服务

    Scenario 我有一个用 C 编写的 Windows 服务 我已经阅读了所有关于如何调试它的谷歌线程 但我仍然无法让它工作 我已经运行 PathTo NetFramework InstallUtil exe C MyService ex
  • 使用 gdb 调试反汇编库

    在Linux和Mac OS X中可以使用strapi和next来调试应用程序而无需调试信息 在 Mac OS X 上 gdb 显示在库内部调用的函数 尽管有时会在每个 stepi 指令中推进多个汇编程序指令 在 Linux 上 当我进入动态
  • 测试是否定义了 gdb 便利变量

    有没有办法测试 gdb 中是否设置了便利变量 例如 gdb if exitcode 0 gt quit gt end Invalid type combination in equality test gdb p exitcode 1 vo
  • Visual Studio 代码调试器未连接到 SAM 本地

    根据 AWS 文档 我将像这样启动本地 SAM sam local start api d 5858 我的 launch json 中有以下内容 version 0 2 0 configurations name Attach to SAM
  • 如何在 Rust 中使用 cfg 检查发布/调试版本?

    使用 C 预处理器很常见 if defined NDEBUG release build endif if defined DEBUG debug build endif Cargo 的大致等价物是 cargo build release以
  • 查找 Java 程序的实际运行时调用树

    假设我有一个包含数百个方法的大程序 根据输入的性质 程序流程正在发生变化 我想我想对原来的流程进行更改 找到调用层次结构 引用并理解流程是一件很大的麻烦 我在 Eclipse 中对此有任何解决方案吗 或者插件 例如 我只需要一个按时间顺序排
  • 如何给objc_exception_throw添加断点?

    这是布拉德 拉森对此的回答SO https stackoverflow com questions 1093999 stack trace or more info on unhandled exception in xcode iphon
  • 生成转储并导致非托管代码崩溃?

    当我的应用程序突然崩溃时 有没有办法获得完整的故障转储 问题是 我怀疑这是由于非托管代码杀死了 net 框架本身 因此 除非在崩溃时应用程序附加了调试器 否则应用程序甚至没有机会处理崩溃 我无法附加调试器并等待 因为崩溃是随机发生的 而且我
  • Golang delve,如何启动调试器并启动正在调试的应用程序?

    我正在尝试设置一个可以远程连接的无头深度调试器 我无法找到一种方法来启动调试服务器 而该服务器不会暂停我正在调试的应用程序 我一直在使用dlv attach headless true listen 2345 attach 32但这会暂停该
  • 无法在 UWP 中调试 .NET Standard 2.0 DLL

    我创建了一个新的 Xamarin Forms 解决方案 升级了所有 NuGet 确保 UWP 版本的目标版本为 16299 并确保 NET Standard 项目的目标版本为 2 0 我运行了该项目并能够很好地调试 NET Standard
  • valgrind 和 iOS SDK 4.2?

    使用 valgrind 运行 iOS 4 2 应用程序时遇到问题 我从 Macports 安装了 valgrind 3 6 0 SVN Xcode 3 2 5 当我修改 main 以运行 valgrind 时 我得到以下输出 Detecte
  • MPI_Comm_Create 挂起而无响应

    我希望多播到不超过 4 台机器的组 MPI bcast 是否仍然比多个单播节省大量时间 请记住我的组规模很小 我编写了以下函数来根据机器的数量和这些机器的等级创建一个新的通信器 void createCommunicator MPI Com
  • ipdb 和 pdb++ 之间的区别?

    Python 有一个名为 pdb 的默认调试器 但社区创建了一些替代品 其中两个是ipdb https github com gotcha ipdb and pdb https github com pdbpp pdbpp 它们似乎迎合了相
  • PHPstorm - 无法在blade.php 文件中设置断点

    我正在开发 Laravel 应用程序 可以很好地调试我的控制器 php 文件 但我还想调试blade php 文件 在我当前的设置中 我遵循了所有 jetbrains 为 Laravel 推荐的设置 https confluence jet
  • Flash 未在调试播放器中显示错误/堆栈跟踪(firefox/chrome/whatnot)

    我正在尝试调试在线默默地失败的应用程序 我 100 确定我正在运行 Flash 调试播放器 为了确保我不会丢失它 我故意抛出一个错误 但 Flash 在浏览器中没有显示任何 stracktrace 我快要失去它了 有什么线索吗 我正在 ch

随机推荐