如何更改编译单元的版本
How to change the version of a compilation unit?
我试图分析为什么一个(相当大的)程序会出错。如果程序崩溃,它会向/tmp写入一个核心转储,我尝试使用gdb对其进行分析。然而,gdb给了我以下错误:
Reading symbols from /home/user/Executable...Dwarf Error:
wrong version in compilation unit header (is 4, should be 2)
[in module /home/user/Executable]
我搜索了一下,在stackoverflow上找到了一个线程,作者认为这是用不同的-g
标志编译部分代码(正是他/她使用的库)的结果。
我已经通过检查了我的可执行文件(C++)和程序中使用的库(C)上的编译单元的版本
readelf --debug-dump=info Executable | grep -A 2 'Compilation Unit @'
显然,可执行文件到处都有4的版本,而库则有2的版本。我想知道是否有可能解决这个问题,以及如何解决?我也很好奇这个问题最初是如何出现的(通过-g标志来摆弄调试级别根本没有帮助)。
TIA
生成单个对象文件(.o)的一组输入称为编译单元;有关更多信息,请参阅维基百科。为了方便起见,"编译单元"通常缩写为"CU"
当用调试信息编译CU时,每个CU具有以CU报头开始的调试信息部分;此标头包含一个版本号。此调试信息的格式称为DWARF。
随着时间的推移,DWARF标准不断发展。对于每个主要版本,版本号都会发生变化。这确保了当DWARF生产者(例如编译器)创建调试信息时,DWARF使用者(例如调试器)知道该期待什么。
当gdb抱怨CU的版本时,它实际上是在抱怨DWARF CU标头中的版本号。
为了避免这个问题,正如您所发现的,您必须确保您的整个软件开发工具链(编译器、链接器、调试器)能够"说出"相同的DWARF版本。您编译最新版本gdb的解决方案是正确的。
来自GCC 4.8发行说明:
在GCC 4.8之前,使用的默认版本是DWARF2。要使GCC 4.8生成较旧的DWARF版本,请将-g与-gdwarf-2或-gdwarv-3 一起使用
在我的情况下,添加
-gdwarf-2 -gstrict-dwarf
使旧的调试器重新工作。不过,我同意在大多数情况下使用较新的GDB版本是最好的解决方案。
我用g++(而不是gcc)编译了库,这产生了所需的编译单元。然而,这仍然导致了gdb抛出的DWARF错误,因此我在机器上编译了gdb的最新版本,最终它现在可以工作了。
- 什么时候调用组成单元对象的析构函数
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 导入库可以跨dll版本工作吗
- 不同翻译单元中不可重载的非内联函数定义
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- VC++本机单元测试,找不到调试符号
- 在clang++预处理器中确定gcc工具链版本
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 将QIcon添加到QTableView单元格
- 不同的Visual Studio版本中缺少.dll
- 用符号版本替换对函数的所有调用
- 用于交叉编译和CMake的预处理器宏的单元测试
- 当用户在qtablewidget中输入单元格时,如何获得信号?C++
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 我需要分发哪些版本的可再分发文件
- 有没有办法在不使用 #ifdef 的情况下不编译发布版本中的单元测试函数体?
- 如何更改编译单元的版本