几乎所有真正的可执行 c++ 程序都链接到 libstdc++.so。这个共享库提供了哪些功能?
我以为很多工作都是在编译时完成的,比如模板实例化,这在编译之前是做不到的。
libstdc++ 为用户空间 C++ 应用程序提供运行时支持。该库中的内容是特定于实现的,并且可能会从一个版本更改为下一个版本。你可能不应该依赖那里的东西。
抛开理论不谈,共享库总是导出函数和/或数据等符号。您可以使用许多工具来查看这些符号。其中之一是nm
;-D
如果您指定参数,它将显示动态符号。所以让我们在 libstdc++.so 上做吧。(列表很大,所以我习惯于head -20
限制它。)
$ nm -D /lib64/libstdc++.so.6 | head -20
U abort
U __assert_fail
000000386565d2b0 T atomic_flag_clear_explicit
000000386565d2f0 T __atomic_flag_for_address
000000386565d2a0 T atomic_flag_test_and_set_explicit
000000386565d2c0 T __atomic_flag_wait_explicit
U bindtextdomain
U btowc
U __ctype_get_mb_cur_max
000000386565dd10 T __cxa_allocate_dependent_exception
000000386565dae0 T __cxa_allocate_exception
U __cxa_atexit
000000386565df10 T __cxa_bad_cast
000000386565df50 T __cxa_bad_typeid
000000386565dfe0 T __cxa_begin_catch
000000386565eb10 T __cxa_call_unexpected
000000386565f160 T __cxa_current_exception_type
000000386565fa00 T __cxa_deleted_virtual
0000003865668990 T __cxa_demangle
000000386565e050 T __cxa_end_catch
这些只是 C++ 运行时提供的一些功能。在上述情况下,大多数是根据 Itanium C++ ABI 实现异常处理的那些。
另请注意,C++ 名称可能会被破坏,例如,您可能会遇到类似于_ZSt9has_facetISt7codecvtIwc11__mbstate_tEEbRKSt6locale的内容。自己拆解它以理解它的含义可能非常困难。所以有另一个工具c++filt
可以帮助解决这个问题,例如将其称为 c++filt _ZSt9has_facetISt7codecvtIwc11__mbstate_tEEbRKSt6locale
.
您甚至可以使用它来对任何看起来被破坏的符号进行破坏,如nm -D /lib64/libstdc++.so.6 | c++filt
.
当然,这适用于任何共享对象,而不仅仅是 C++ 运行时。
如果你真的想要在库中明确定义的函数列表,你可以nm
在库文件上使用命令:
nm -D -C -g --defined-only /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++.so | less
如果将是巨大的,详尽的......但它向您展示了导出的内容。