我正在开发一个嵌入式系统,在使用 nm 分析二进制文件时,我发现了许多来自标准库函数的符号,例如:
00001524 std::time_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::_M_extract_via_format(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, tm*, char const*) const [clone .localalias]
这意味着有一个
std::time_get
函数被链接进来,它有 1524 字节大。
我想找出是什么调用链导致了对 std::time_get
的调用,因为我实际上并没有在代码的任何部分中引用它。
尝试使用链接器标志
--cref
并查看映射文件,我可以找到该符号,但找不到调用它的内容。它只告诉我 libstdc++_nano.a(locale-inst.o)
引用了它:
.text._ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc
0x00000000080a07bc 0x5fc /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)
0x00000000080a07bc std::time_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::_M_extract_via_format(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, tm*, char const*) const
我怎样才能从那里找到来电者?
您可以使用链接器
-y
标志来回答这个问题(尽管这非常乏味)。
示例:
// foo.c
int foo() { return 42; }
// bar.c
int bar() { return foo(); }
// main.c
int main() { return bar(); }
gcc -w -c main.c foo.c bar.c
ar r libfoo.a foo.o
ar r libbar.a bar.o
gcc main.o -L. -lbar -lfoo -Wl,-y,foo
/usr/bin/ld: ./libbar.a(bar.o): reference to foo
/usr/bin/ld: ./libfoo.a(foo.o): definition of foo
这告诉您
foo
已被选入链接,因为 bar.o
有对其的引用。重复bar
:
gcc main.o -L. -lbar -lfoo -Wl,-y,bar
/usr/bin/ld: main.o: reference to bar
/usr/bin/ld: ./libbar.a(bar.o): definition of bar
您还可以使用
-M
标志来获取相同的信息:
gcc main.o -L. -lbar -lfoo -Wl,-M
将会有类似这样的输出:
.text 0x0000000000001070 0xb9 /usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o
.text 0x0000000000001129 0x10 main.o
0x0000000000001129 main <<<---
.text 0x0000000000001139 0x10 ./libbar.a(bar.o)
0x0000000000001139 bar <<<---
.text 0x0000000000001149 0xb ./libfoo.a(foo.o)
0x0000000000001149 foo <<<---
<<<---
标记显示哪个符号导致相应的.o
被拉入链接。