GCC链接C程序时无法找到共享库中已存在的符号求助
链接libunwind时出现未定义引用错误
问题场景
从libunwind源码编译共享库后,将库文件安装到/usr/local/lib目录,目录结构如下:
/usr/local/lib/ ├── ... ├── libunwind-x86_64.a ├── libunwind-x86_64.la ├── libunwind-x86_64.so -> libunwind-x86_64.so.8.0.1 ├── libunwind-x86_64.so.8 -> libunwind-x86_64.so.8.0.1 ├── libunwind-x86_64.so.8.0.1 ├── libunwind.a ├── libunwind.la ├── libunwind.so -> libunwind.so.8.0.1 ├── libunwind.so.8 -> libunwind.so.8.0.1 └── libunwind.so.8.0.1
使用以下命令编译链接测试程序时,出现未定义引用错误:
gcc -DUNW_LOCAL_ONLY -L/usr/local/lib -lunwind test.c -o run -v
错误信息:
/usr/bin/ld: /tmp/ccVefxO3.o: in function `main': test.c:(.text+0x4c): undefined reference to `_Ux86_64_getcontext' /usr/bin/ld: test.c:(.text+0x65): undefined reference to `_ULx86_64_init_local' /usr/bin/ld: test.c:(.text+0x8f): undefined reference to `_ULx86_64_get_reg' /usr/bin/ld: test.c:(.text+0xa5): undefined reference to `_ULx86_64_step' collect2: error: ld returned 1 exit status
环境信息:
- GCC版本:
9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) - 运行平台:
Ubuntu-20.04(WSL2)-x86_64
关键细节
通过readelf命令确认,报错中缺失的符号确实存在于/usr/local/lib/libunwind.so中:
$ readelf -s /usr/local/lib/libunwind.so | grep "_Ux86_64_getcontext\|_ULx86_64_get_reg\|_ULx86_64_init_local\|_ULx86_64_step"
输出结果:
48: 0000000000004a80 14 FUNC GLOBAL DEFAULT 11 _ULx86_64_init_local 51: 0000000000004a90 46 FUNC GLOBAL DEFAULT 11 _ULx86_64_init_local2 70: 0000000000006530 113 FUNC GLOBAL DEFAULT 11 _Ux86_64_getcontext 71: 00000000000053e0 1336 FUNC GLOBAL DEFAULT 11 _ULx86_64_step 73: 0000000000003e80 26 FUNC GLOBAL DEFAULT 11 _ULx86_64_get_reg 146: 00000000000065a1 38 FUNC LOCAL DEFAULT 11 _Ux86_64_getcontext_trace 205: 0000000000004a90 46 FUNC GLOBAL DEFAULT 11 _ULx86_64_init_local2 206: 0000000000006530 113 FUNC GLOBAL DEFAULT 11 _Ux86_64_getcontext 212: 00000000000053e0 1336 FUNC GLOBAL DEFAULT 11 _ULx86_64_step 226: 0000000000003e80 26 FUNC GLOBAL DEFAULT 11 _ULx86_64_get_reg 259: 0000000000004a80 14 FUNC GLOBAL DEFAULT 11 _ULx86_64_init_local
测试代码test.c:
#include <libunwind.h> #include <memory.h> #define StackFrameDepthMax 100 int main() { unsigned int depth = 0; unw_cursor_t cursor; unw_context_t context; unw_word_t pcArray[StackFrameDepthMax]; memset((void*)pcArray, 0, sizeof(pcArray)); unw_getcontext(&context); unw_init_local(&cursor, &context); while (unw_step(&cursor) > 0) { unw_get_reg(&cursor, UNW_REG_IP, &pcArray[depth]); depth++; } }
问题分析与解决
核心原因:链接库的顺序错误
GCC链接器遵循按需链接规则:处理库文件时,只会保留当前已被引用的符号,未被引用的符号会被直接丢弃。你当前的命令把-lunwind放在源文件test.c前面,链接器处理库时还不知道需要哪些符号,导致后续处理目标文件时找不到对应符号。
解决步骤
调整编译命令,将源文件放在库参数之前:
gcc -DUNW_LOCAL_ONLY -L/usr/local/lib test.c -o run -v -lunwind
额外验证
如果问题仍存在,可尝试同时链接平台相关的libunwind-x86_64库:
gcc -DUNW_LOCAL_ONLY -L/usr/local/lib test.c -o run -v -lunwind -lunwind-x86_64
内容的提问来源于stack exchange,提问作者Xshell
相关产品推荐
相关产品推荐

