运行时而不是加载时出现符号查找错误

Symbol lookup error at runtime instead of load time

我有一个应用程序使用来自 .so 共享库的 class Foo。我遇到了一个问题,它在 运行 时打印

<appname>: symbol lookup error: <appname>: undefined symbol: <mangled_Foo_symbol_name>

现在,原来未损坏的符号是 class Foo 的构造函数,问题只是加载了旧版本的库,其中还不包含 Foo。

我的问题不是关于解决错误(这显然是为了使用正确的库),而是为什么它出现在 运行time 而不是 time of加载/启动。

导致错误的代码行只是实例化了 class Foo 的一个对象,所以我在这里没有使用任何类似 dlopen 的东西,至少没有明确/据我所知。

相比之下,如果我从加载搜索路径中删除整个库,我会在启动时收到此错误:

<appname>: error while loading shared libraries: libname.so.2: cannot open shared object file: No such file or directory

当加载路径上的gcc/libstdc++版本错误时,启动时也会报错:

<appname>: /path/to/gcc-4.8.0/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by <appname>)


这种 "fail fast" 行为更令人满意,我不想先 运行 我的应用程序一段时间,直到我最终意识到它使用了错误的库。 是什么导致加载错误出现在 运行 时间,我怎样才能让它立即出现?

我认为你不能静态 link .so 库。如果你想避免 load/run 时间错误,你必须使用所有静态库 (.a)。如果您没有静态版本的库和源代码,请尝试查找一些 statifier。谷歌搜索后,我发现很少有静态化器,但不知道它们是如何工作的,所以把那部分留给你。

来自 ld.so 的手册页:

ENVIRONMENT

  • LD_BIND_NOW (libc5; glibc since 2.1.1) If set to a nonempty string, causes the dynamic linker to resolve all symbols at program startup instead of deferring function call resolution to the point when they are first referenced. This is useful when using a debugger.
  • LD_WARN (ELF only)(glibc since 2.1.3) If set to a nonempty string, warn about unresolved symbols.