是什么让GDB拒绝破产?

我在这里不知所措。 我正在用C编写一个编译器(用于爱好),并使用GDB 7.3在amd64 Linux 2.6.32上使用GCC 4.6.1进行编译。 标志是“-Wall -Wextra -O0 -g”,除了通常的-I和诸如此类之外。 我有一个函数,其目的是报告一个解析错误,定义如下:

void cerror_at (struct lex *lex, struct token *tok, const char *fmt, ...) 

除了变量,没有什么奇怪的。 问题是GDB不会破坏它。 我已经尝试了各种我能想到的方法(函数中的断点,函数内部,调用它之前,你给它命名),但是只要我的程序在函数内部,我就会收到类似“警告:删除断点时出错”的消息0“和GDB只是让程序完成。 它已经没有任何问题(我已经修复了我试图找到的错误,并且一切都按照它应该运行),但我无法进入该function。 关于什么可能导致这个的任何想法?

编辑:更多信息! GDB将断点设置为0x403057。 该函数从0x403025开始。 看看这部分反汇编:

 0x0000000000403053 : test %al,%al 0x0000000000403055 : je 0x403077  

此时,它会向前跳到0x403077(超过断点)。 我已经validation了将断点放在“je”之前的地址,以及跳转目标0x403077处或之后的地址,但不是介于两者之间(GDB试图放置它的地址)。 为什么GDB将断点放在函数的中间? 甚至GDB告诉我函数的地址实际上是0x403025。

也许我只是密集,但我遇到调试器拒绝破解的最常见原因是最简单的原因。

  1. 我正在尝试调试的代码与调试器中的代码不完全匹配。
  2. 我忘了使用调试选项编译该库。

当你收到类似的调试错误时,请务必检查这两个错误,即使你认为这不是问题。

这听起来像是GDB中的一个错误。 特别是, Error removing breakpoint 0是非常可疑的(它是一个断点GDB自动插入某处;用户插入的断点有正数)。

您应该尝试创建一个简化的测试用例并在此处提交错误。

如评论中所述,您应该尝试了解编译生成的机器代码:

在GDB中,你可以通过disassemble cerror_at看到实际的函数代码,它应该给出类似(x86_64)的东西:

 (gdb) disassemble dive Dump of assembler code for function dive: 0x0000000000400504 <+0>: push %rbp 0x0000000000400505 <+1>: mov %rsp,%rbp 0x0000000000400508 <+4>: sub $0x10,%rsp 0x000000000040050c <+8>: mov %edi,-0x4(%rbp) 0x000000000040050f <+11>: mov -0x4(%rbp),%eax 0x0000000000400512 <+14>: add $0x1,%eax 0x0000000000400515 <+17>: mov %eax,%edi 0x0000000000400517 <+19>: callq 0x400504  0x000000000040051c <+24>: leaveq 0x000000000040051d <+25>: retq End of assembler dump. 

然后检查实际调用子例程:在函数调用之前中断执行一些指令,然后:

  (gdb) x/5i $p => 0x400539 : mov $0x1,%esi 0x40053e : mov %rax,%rdi 0x400541 : callq 0x400408  0x400546 : mov $0x1,%edi -->0x40054b : callq 0x400504  <------ 

输出应该与另一个CPU架构略有不同,但您应该能够看到指向函数地址的分支指令。

-

并且您可以在看到Error removing breakpoint 0的时刻之前执行maint info breakpoint ,以了解breakpoint 0设置位置,这可能有助于理解它的错误。

根据您的最新编辑,我敢打赌这是一个编译器错误。 具体来说,我打赌生成DWARF调试信息存在问题,这是GDB用来映射目标代码中的地址和源中的文件/过程/行号之间的问题。

您可以尝试使用-gdwarf-4-gdwarf-3或甚至-gdwarf-2进行实验,看看它是否有任何区别。

如果你可以将它简化为一个简单的测试用例,我怀疑gcc开发人员会接受它作为一个bug。

当然,这也可能是GDB中的一个错误。 但鉴于这种行为,我认为这种可能性较小。