嵌入式系统中如何查找导致std::time_get被链接的调用链?
查找嵌入式二进制中未显式引用的标准库函数调用链
针对你遇到的std::time_get::_M_extract_via_format被隐式链接进二进制的问题,可以通过以下步骤追溯调用链:
1. 反汇编二进制文件定位调用指令
使用objdump反汇编目标ELF文件,搜索目标函数的修饰后名称(mangled name),找到调用它的指令:
arm-none-eabi-objdump -d your_project.elf | grep -B5 -A5 "_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_format"
输出中会包含调用该函数的跳转指令(如ARM的bl或bx),记录指令对应的内存地址。
2. 将调用地址转换为具体函数
用addr2line工具将调用地址映射到源代码或函数符号:
arm-none-eabi-addr2line -e your_project.elf 0x调用地址
如果编译时带有调试信息(-g),还能直接定位到具体代码行。若没有调试信息,可结合readelf查看符号表:
arm-none-eabi-readelf -s your_project.elf | grep 0x调用地址
3. 分析库文件中的调用关系
既然该函数来自libstdc++_nano.a(locale-inst.o),直接反汇编这个目标文件,找到内部调用它的上层函数:
arm-none-eabi-objdump -d /opt/st/stm32cubeide_1.10.1/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.linux64_1.0.0.202111181127/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+dp/hard/libstdc++_nano.a(locale-inst.o) | grep -B10 -A10 "_ZNKSt8time_get..."
找到调用它的函数后,再回到自己的二进制文件中,重复步骤1-2,追溯该上层函数的调用者。
4. 链接阶段追踪符号引用
在编译链接时添加--trace-symbol选项,让链接器输出所有引用目标符号的对象文件:
# 在编译脚本中添加链接器参数 -Wl,--trace-symbol=_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_format
这会直接显示哪些文件(包括你的代码文件或库文件)引用了该符号,快速缩小范围。
5. 排查C++隐式模板实例化或隐式调用
std::time_get属于C++ locale和时间格式化相关组件,可能是以下隐式操作触发的链接:
- 代码中使用了
std::cin、std::get_time等时间输入/格式化函数 - 包含了
<iostream>、<locale>、<chrono>等头文件后,模板被隐式实例化 - 某些第三方库或系统组件间接调用了locale相关功能
内容的提问来源于stack exchange,提问作者Florian Humblot
相关产品推荐
相关产品推荐

