GCC 4.8即使使用-gdwarf-2选项,在编译单元头中仍会插入版本4

9

我使用GCC 4.8编译了一个应用程序,现在想在没有GDB 7.5+的旧系统上进行调试(据说GDB 7.5+增加了对DWARF-4的支持)。但是升级该系统上的GDB并不可行。由于GDB输出以下消息,我无法进行调试:

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

我尝试按照其他问题中建议的使用-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

即使您按照以下方式编译最小的C程序,仍会发生此情况:
/home/MuchToLearn/src> cat main.c
int main(void)
{
  return 0;
}
/home/MuchToLearn/src> gcc -gdwarf-2 -gstrict-dwarf main.c

我有点不明白,如果使用-gdwarf-2选项无法生成可以由只支持DWARF-2的旧版GDB进行调试的二进制文件,那么这个选项的意义是什么?
编辑:Employed Russian的回答是正确的。版本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

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


可能您正在使用使用较新dwarf版本编译的库?除非您正在静态链接某些内容,否则您应该只有一个'Compilation Unit'子句... - o11c
除非是像glibc这样的隐式问题,否则我已经没有更多的想法了。即使是在问题中最小的程序中,它也会发生,该程序甚至不使用printf() - MuchToLearn
1个回答

5
即使您编译一个最小的C程序,也会发生这种情况:
即使您编译一个最小的C程序,也会静态链接libc的部分(即crt1.o,crtbegin.o等)。
您应该验证具有版本4的编译单元确实来自您的程序,而不是来自库(只需查看它们的DW_AT_name和DW_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

如果版本4的对象只是或类似的文件,请注意可以安全地在这些对象上运行 -- 除非您必须调试libc启动问题(这不太可能),否则不会损失太多。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接