使用Clang-17与LLD-17编译链接含静态库的C++程序时调试符号重叠问题的解决方法咨询
嘿,各位大佬好!我最近在用LLVM-17工具链编译一个C++项目时碰到了调试符号的问题,想请教下有没有办法在保留LLD-17作为链接器的前提下解决这个问题。
具体情况是这样的:我用Clang++-17编译代码生成目标文件,打包成静态库后,再用LLD-17链接生成可执行文件。但当我用llvm-dwarfdump-17 --verify <binary_file>检查调试符号时,出现了大量调试信息条目重叠的错误。不过如果换成GNU ld链接的话,符号就能正常合并,这个问题就消失了。
我准备了一个可复现的最小示例,包含三个文件:
1. main.cpp
#include "lib.h" #include <iostream> int main() { std::cout << "Hello, "; bar(); }
2. lib.h
#pragma once extern void bar();
3. lib.cpp
#include "lib.h" #include <iostream> void bar() { std::cout << "world!" << std::endl; }
我的环境配置是:
- LLVM-17工具链
- GCC版本9.4.0
- GNU binutils版本2.34
- Linux内核5.15.0-117-generic,x86_64架构
编译脚本如下:
#!/usr/bin/env bash clang++-17 -O0 -g -gdwarf-4 \ -v \ -std=c++26 \ -stdlib=libc++ \ -fno-standalone-debug \ -fPIC \ -c lib.cpp \ -o lib.o clang++-17 -O0 -g -gdwarf-4 \ -v \ -std=c++26 \ -stdlib=libc++ \ -fno-standalone-debug \ -c main.cpp \ -o main.o ar -rcs lib.a lib.o clang++-17 -O0 -g -gdwarf-4 \ -v \ -std=c++26 \ -stdlib=libc++ \ -fuse-ld=lld-17 \ main.o \ lib.a \ -o a.out
用llvm-dwarfdump-17 --verify a.out检测时,会出现类似这样的错误:
error: DIEs have overlapping address ranges:
0x00009dd3: DW_TAG_subprogram [84] * (0x00005f6a)
DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
DW_AT_high_pc [DW_FORM_data4] (0x0000007d)
DW_AT_frame_base [DW_FORM_exprloc] (DW_OP_reg6)
DW_AT_object_pointer [DW_FORM_ref4] (cu + 0x3e8d => {0x00009dec})
DW_AT_decl_line [DW_FORM_data2] (778)
DW_AT_specification [DW_FORM_ref4] (cu + 0x2ae7 => {0x00008a46} "_ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenB8ue170006Ec")
0x0000986f: DW_TAG_subprogram [82] * (0x00005f6a)
DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
DW_AT_high_pc [DW_FORM_data4] (0x00000030)
DW_AT_frame_base [DW_FORM_exprloc] (DW_OP_reg6)
DW_AT_specification [DW_FORM_ref4] (cu + 0x024e => {0x000061ad} "_ZNSt3__111char_traitsIcE6lengthB8ue170006EPKc")
看起来问题出在LLD-17没有正确合并来自不同目标文件的调试符号?有没有什么编译或链接选项可以让LLD正确处理这些调试符号,避免重叠错误呢?麻烦各位大佬支支招!
内容来源于stack exchange

