为什么 GDB 需要可执行文件和核心转储?

10 core-dump gdb

我正在使用核心转储进行调试,请注意 gdb 需要您提供可执行文件和核心转储。为什么是这样?如果核心转储包含进程使用的所有内存,那么核心转储中不包含可执行文件吗?也许不能保证整个 exe 被加载到内存中(尽管单个可执行文件通常没有那么大),或者核心转储毕竟不包含所有相关内存?是用于符号吗(也许它们没有正常加载到内存中)?

X T*_*ian 15

核心转储只是您程序内存占用的转储,如果您知道一切都在哪里,那么您就可以使用它。

您使用可执行文件是因为它解释了事物在内存中的位置(根据逻辑地址),即核心文件。

如果您使用命令objdump,它将转储有关您正在调查的可执行对象的元数据。以名为 a.out 的可执行对象为例。

objdump -h a.out仅转储标题信息,您将看到名为例如的部分。.data.bss.text(还有更多)。这些通知内核加载器可以在对象中的何处找到各个部分,以及应该在进程地址空间中的何处加载该部分,以及对于某些部分(例如 .data .text)应该加载什么。(.bss 部分不包含文件中的任何数据,但它指的是在进程中为未初始化数据保留的内存量,它用零填充)。

可执行目标文件的布局符合标准 ELF。

objdump -x a.out - 倾倒一切

如果可执行对象仍然包含它的符号表(它没有被剥离 -man strip并且您曾经-g生成调试生成以gcc 假设 ac 源代码编译),那么您可以通过符号名称检查核心内容,例如,如果您有一个变量/缓冲区在您的源代码中命名为inputLine,您可以使用该名称gdb来查看其内容。即gdb会知道从程序初始化数据段开始的偏移量,其中inputLine开始和该变量的长度。

进一步阅读第 1第 2以及详细的可执行和链接格式 (ELF) 规范


在@mirabilos 评论后更新。

但是如果使用符号表

$ gdb --batch -s a.out -c core -q -ex "x buf1"
Run Code Online (Sandbox Code Playgroud)

生产

 0x601060 <buf1>:    0x72617453
Run Code Online (Sandbox Code Playgroud)

然后不使用符号表并直接检查地址,

$ gdb --batch -c core -q -ex "x 0x601060"
Run Code Online (Sandbox Code Playgroud)

生产

0x601060:   0x72617453
Run Code Online (Sandbox Code Playgroud)

我直接检查了内存,没有使用第二个命令中的符号表。


我也看到,@user580082 的回答进一步增加了解释,并且会投票。

  • 从未听说过“基本堆栈部分”。**.bss**(历史上)是“由符号开始的块”,实际上是“单元化数据”,而 **.data** 是“初始化数据”,**text**(不是 .code)用于存储机器码。二进制文件中没有堆栈部分,因为堆栈是在运行时创建的。 (6认同)
  • @jlliagre你是对的,我错误地调用了.text .code(因为我在撰写答案时正在考虑解释)-已更新。我错误地认为 bss 的名称不正确,并更新了我的答案,但避免了 *Block Started by Symbol 因为我认为它并没有真正添加到等式中,并解释了它被用作未初始化的数据,这是我们的达成共识。谢谢 - 我感谢您纠正此帖子的评论。 (2认同)