GCC 4.8在编译单元头中插入版本4,即使使用-gdwarf-2也是如此

Muc*_*arn 9 c gcc elf dwarf

我用GCC 4.8编译了一个应用程序,我试图在一个没有GDB 7.5+的旧系统上调试它(据说它增加了对DWARF-4的支持).在该系统上升级GDB不是一种选择.我无法调试它,因为GDB输出以下消息:

Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module a.out]
Run Code Online (Sandbox Code Playgroud)

我尝试使用-gdwarf-2 -gstrict-dwarf进行编译,如其他问题所示,但编译器会继续插入一些版本4的编译单元头:

/tmp> readelf --debug-dump=info a.out | grep -A2 'Compilation Unit @'
readelf: Warning: CU at offset 6b contains corrupt or unsupported version number: 4.
readelf: Warning: CU at offset 1eb contains corrupt or unsupported version number: 4.
  Compilation Unit @ offset 0x0:
   Length:        0x67 (32-bit)
   Version:       2
--
  Compilation Unit @ offset 0x6b:
   Length:        0x84 (32-bit)
   Version:       4
--
  Compilation Unit @ offset 0xf3:
   Length:        0x62 (32-bit)
   Version:       2
--
  Compilation Unit @ offset 0x159:
   Length:        0x8e (32-bit)
   Version:       2
--
  Compilation Unit @ offset 0x1eb:
   Length:        0x136 (32-bit)
   Version:       4
--
  Compilation Unit @ offset 0x325:
   Length:        0x62 (32-bit)
   Version:       2
Run Code Online (Sandbox Code Playgroud)

即使您按如下方式编译最小C程序,也会发生这种情况:

/home/MuchToLearn/src> cat main.c
int main(void)
{
  return 0;
}
/home/MuchToLearn/src> gcc -gdwarf-2 -gstrict-dwarf main.c
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么吗?如果不生成可以由仅支持DWARF-2的旧GDB版本调试的二进制文件,那么使用-gdwarf-2选项有什么意义呢?

编辑:雇用俄罗斯的答案是正确的.版本4的编译单元来自/usr/lib/crt1.o/usr/lib/libc_nonshared.a.为了解决这个问题,我将它们复制到本地目录中并删除了它们的调试符号strip -g.然后,我将可执行文件链接如下:

ld -o main -dynamic-linker /lib/ld-linux.so.2 crt1.o /usr/lib/crti.o main.o /lib/libc.so.6 libc_nonshared.a /usr/lib/crtn.o
Run Code Online (Sandbox Code Playgroud)

生成的可执行文件不包含任何版本4编译单元,GDB停止抱怨.

Emp*_*ian 5

即使您按如下方式编译最小C程序,也会发生这种情况:

即使这个最小的程序将静态链接libc中的部分(即crt1.o,crtbegin.o等).

您应该验证具有版本4的编译单元是否真的来自您的程序,而不是来自库(只需查看它们的DW_AT_nameDW_AT_comp_dir).

我的gcc-4.8:gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4当我要求它时产生版本2:

gcc -g -c t.c
readelf -wi t.o | grep -A2 'Compilation Unit'
  Compilation Unit @ offset 0x0:
   Length:        0x4e (32-bit)
   Version:       4

gcc -gdwarf-2 -c t.c
readelf -wi t.o | grep -A2 'Compilation Unit'
  Compilation Unit @ offset 0x0:
   Length:        0x52 (32-bit)
   Version:       2
Run Code Online (Sandbox Code Playgroud)

如果版本4对象真的只是crt1.o或类似,请注意您可以安全地运行strip -g这些对象 - 您不会失去太多(除非您必须调试libc启动问题,这是不可能的).