-rdynamic使backtrace能显示函数名而非仅地址,因其将所有符号加入动态符号表供运行时查找;它等价于--export-dynamic,仅作用于链接阶段,不影响编译或静态库。

-rdynamic 的作用是让链接器把所有符号(包括未直接引用的)都加入到动态符号表中,以便运行时能被 dlsym、backtrace 等函数查到。
为什么 backtrace 需要 -rdynamic
默认情况下,可执行文件的动态符号表只保留用于动态链接的符号(比如 printf 这类 libc 函数),而你自己定义的函数名(如 foo、main_loop)不会写入该表。调用 backtrace + backtrace_symbols 时,后者依赖这个表做地址→函数名映射——没加 -rdynamic 就只能看到十六进制地址,看不到函数名。
- 不加
-rdynamic:backtrace_symbols输出类似./a.out[0x401234] - 加了之后:
./a.out(foo+0x12) [0x401234]
-rdynamic 和 -export-dynamic 是一回事
-rdynamic 是 GNU ld 链接器的短选项,等价于 --export-dynamic。它只影响最终链接阶段,对编译(gcc -c)或汇编无作用。
- 必须放在链接命令末尾,且要和目标文件、库一起传给
gcc:例如gcc main.o -rdynamic -o prog - 不能只写在编译阶段:
gcc -c -rdynamic main.c会忽略该参数,不报错但无效 - 和
-shared一起用时也有效,适用于调试动态库内部调用栈
它和 -g 不是一回事,但常一起用
-g 控制的是调试段(.debug_*),供 gdb 使用;-rdynamic 控制的是动态符号表(.dynsym),供运行时符号查找使用。两者互不依赖,但实际调试中经常同时启用:
-
gcc -g -rdynamic main.c -o prog→ 既支持gdb单步,也支持backtrace显示函数名 - 生产环境若禁用调试信息(
-g0),但还想保留栈回溯可读性,仍可单独用-rdynamic - 注意:
-rdynamic会让二进制略大(多存符号名),但不影响运行时内存占用
真正容易被忽略的是:它只对最终可执行文件生效,静态库(.a)里的符号即使加了 -rdynamic 也不会导出——必须确保那些函数已链接进主程序,且未被链接器优化掉(比如未被 --gc-sections 删除)。











