我正在尝试加载一个共享库(插件)我在Linux ARM平台下使用dlopen提供了(封闭源代码)。我正试图以这种方式加载:
void* handle = dlopen(<library_path>/<library_name>, RTLD_NOW);
结果是此消息失败:
Failed to load <library_path>/<library_name>: undefined symbol: <symbol_name>.
我试图用nm查看库内部,但似乎lib被剥离,找不到符号。我也尝试过使用readelf -s,事实上,我得到了这个结果:
12663: 00000000 0 NOTYPE GLOBAL DEFAULT UND <symbol_name>
通过阅读,我得到readelf -s返回所有符号,包括在它引用的库中定义的那些符号。
this问题的答案对我来说并不完全清楚:这是一个应该在库中的符号,它不存在,因为它是以错误的方式编译的,或者这是一个符号我'我应该找别的地方? readelf -d的输出似乎表明我提供了所有需要的共享库。可能这个错误与我正在编译可执行文件的方式中的错误有关,或者这与加载程序无关?
另外,我读到了每列的含义,但这些值很奇怪。你如何解释这个符号描述?为什么地址为0?为什么键入NOTYPE?
答案 0 :(得分:5)
未定义的符号:X表示始终应该从一个已加载的库中导出X,但事实并非如此。您应该找到所请求的库符号并链接到它。
您应该知道此消息始终是库的问题的结果,这不是错误。图书馆应该知道如何获得它的所有符号。如果没有,您可以将可执行文件链接到所需的库,这样当您加载插件时,已知请求的符号。
此错误可能有更复杂的原因。如果插件和主应用程序都链接到库,那么尝试链接它可能会以未定义的符号结束。如果主应用程序和插件使用不同版本的库(即插件使用较新版本),则可能会发生这种情况。然后在加载插件时,旧版本已加载,因此加载器假定一切正常,但较新版本可能包含新符号。如果插件使用它们,您将得到未定义的符号错误。
答案 1 :(得分:0)
如果在链接命令中静态库的顺序对于应用程序来说是错误的,也会出现此问题。 Unix ld链接器要求在引用函数的库之后指定实现函数的库。
当我尝试构建libtesseract共享库时遇到了这个麻烦,它从一个自定义位置(不是来自主机的标准libz,而是也从源代码手动构建)获取libz库。我在下面举了一个例子:
错误的链接顺序(-llept之前为-lz):
$ g++ -fPIC -DPIC -shared -nostdlib /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/5/crtbeginS.o -Wl,--whole-archive ....(some libs) -Wl,--no-whole-archive -L/home/build/jenkins/workspace/tesseract/zlib/bin/lib -L/home/build/jenkins/workspace/tesseract/leptonica/bin/lib -L/usr/lib/gcc/x86_64-linux-gnu/5 -L/usr/lib/x86_64-linux-gnu -lz -llept -lstdc++ -lm -lc -lgcc_s /usr/lib/gcc/x86_64-linux-gnu/5/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o -g -O2 -Wl,-soname -Wl,libtesseract.so.4 -o .libs/libtesseract.so.4.0.1
检查“ nm -D”:
$ nm -D .libs/libtesseract.so.4.0.1 | grep deflateInit
U deflateInit_
检查“ dlopen”:
Cannot load ./tesseract/src/api/.libs/libtesseract.so.4.0.1 (./tesseract/src/api/.libs/libtesseract.so.4.0.1: undefined symbol: deflateInit_)
之所以发生这种情况,是因为链接器正在循环处理在命令行中传递的所有静态库,并且跳过了任何先前版本未使用的静态库。因为在检查libz.a时,链接器会看到所有已检查的库都没有使用libz.a中的任何功能,所以链接器只是“忘记了” libz.a。
正确的链接顺序(-llept之后为-lz):
$ g++ -fPIC -DPIC -shared -nostdlib /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/5/crtbeginS.o -Wl,--whole-archive ....(some libs) -Wl,--no-whole-archive -L/home/build/jenkins/workspace/tesseract/zlib/bin/lib -L/home/build/jenkins/workspace/tesseract/leptonica/bin/lib -L/usr/lib/gcc/x86_64-linux-gnu/5 -L/usr/lib/x86_64-linux-gnu -llept -lz -lstdc++ -lm -lc -lgcc_s /usr/lib/gcc/x86_64-linux-gnu/5/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o -g -O2 -Wl,-soname -Wl,libtesseract.so.4 -o .libs/libtesseract.so.4.0.1
检查“ nm -D”:
$ nm -D .libs/libtesseract.so.4.0.1 | grep deflateInit
000000000041fb5b T deflateInit_
000000000041fba3 T deflateInit2_
“ dlopen”这次没有显示此错误。