[英]Runtime “symbol lookup error” after compilation and linking of .so
first of all I've searched this one quite a bit and haven't managed to find a question with the same situation. 首先,我已经对此进行了相当多的搜索,但并没有找到相同情况的问题。
I'm building a 32 bit plugin as a shared-object on a 64 bit machine and using cpp-redis . 我在64位计算机上使用cpp-redis构建32位插件作为共享库。 cpp-redis built fine and I used a cmake toolchain to force 32 bit, checked the .o files during build and confirmed they are 32 bit.
cpp-redis构建良好,我使用cmake工具链强制使用32位,在构建过程中检查了.o文件,并确认它们是32位。
I compiled and linked my very basic program (consisting of one main source file and an extra lib for talking to my host application since this is a plugin). 我编译并链接了非常基本的程序(由一个主源文件和一个用于与主机应用程序对话的额外lib组成,因为这是一个插件)。
Upon running loading the plugin into the host app, I am greeted with: 在将插件加载到主机应用程序中后,我受到欢迎:
symbol lookup error: plugins/samp-redis.so: undefined symbol: _ZN9cpp_redis16redis_subscriberC1ERKSt10shared_ptrINS_7network10io_serviceEE
I'm pretty stumped as I've added the cpp-redis dir to the linker path with -L and the library with -l, here's my comp/link lines: 我很沮丧,因为我已使用-L将cpp-redis目录添加到链接器路径,并使用-l将其添加到库,这是我的comp / link行:
(SDK_DIR is my host app sdk, pretty small and minimal set of .c/h files) (SDK_DIR是我的主机应用程序sdk,非常小且最小的.c / h文件集)
g++ -fpermissive -fPIC -m32 -std=c++11 -c -O3 -w -D LINUX -I$(SDK_DIR) -I$(SDK_DIR)/amx -I/usr/local/include/cpp_redis (source .cpp files...)
g++ -v -Wall -O2 -m32 -fshort-wchar -s -shared -L/usr/local/lib/ -lcpp_redis -o $(OUTFILE) *.o
Which runs fine with no errors, I ran the link stage with -v to check the flags went in properly and it all looks fine. 运行正常,没有错误,我用-v运行了链接阶段,以检查标记是否正确进入,一切看起来都很好。
(added some newlines for readability) (添加了一些换行符以提高可读性)
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure
-v
--with-pkgversion='Debian 4.9.2-10'
--with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs
--enable-languages=c,c++,java,go,d,fortran,objc,obj-c++
--prefix=/usr
--program-suffix=-4.9
--enable-shared
--enable-linker-build-id
--libexecdir=/usr/lib
--without-included-gettext
--enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.9
--libdir=/usr/lib
--enable-nls
--with-sysroot=/
--enable-clocale=gnu
--enable-libstdcxx-debug
--enable-libstdcxx-time=yes
--enable-gnu-unique-object
--disable-vtable-verify
--enable-plugin
--with-system-zlib
--disable-browser-plugin
--enable-java-awt=gtk
--enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre
--enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64
--with-arch-directory=amd64
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc
--enable-multiarch
--with-arch-32=i586
--with-abi=m64
--with-multilib-list=m32,m64,mx32
--enable-multilib
--with-tune=generic
--enable-checking=release
--build=x86_64-linux-gnu
--host=x86_64-linux-gnu
--target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9.2 (Debian 4.9.2-10)
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/
:/usr/lib/gcc/x86_64-linux-gnu/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/
:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/32/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/
:/lib/../lib32/
:/usr/lib/../lib32/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../
:/lib/
:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-Wall' '-O2' '-m32' '-fshort-wchar' '-s' '-shared' '-L/usr/local/lib/' '-o' 'samp-redis.so' '-shared-libgcc' '-mtune=generic' '-march=i586'
/usr/lib/gcc/x86_64-linux-gnu/4.9/collect2
-plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
-plugin-opt=-fresolution=/tmp/cc0Lo5po.res
-plugin-opt=-pass-through=-lgcc_s
-plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc_s
--sysroot=/
--build-id
--eh-frame-hdr
-m elf_i386
--hash-style=gnu
-shared
-o samp-redis.so
-s /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/32/crtbeginS.o
-L/usr/local/lib/
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/32
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32
-L/lib/../lib32
-L/usr/lib/../lib32
-L/usr/lib/gcc/x86_64-linux-gnu/4.9
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../..
-lcpp_redis amxplugin2.o amxplugin.o main.o
-lstdc++
-lm
-lgcc_s
-lc
-lgcc_s /usr/lib/gcc/x86_64-linux-gnu/4.9/32/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/crtn.o
Am I misunderstanding the linking stage or statically linking? 我是误解链接阶段还是静态链接? It has been a while since I did C++... I'm all about Python and Go these days!
自从我做C ++以来已经有一段时间了...这些天我都在关注Python和Go!
EDIT: 编辑:
Compiling with -W,--no-undefined
results in this output: 使用
-W,--no-undefined
编译时-W,--no-undefined
此输出中-W,--no-undefined
结果:
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure
-v
--with-pkgversion='Debian 4.9.2-10'
--with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs
--enable-languages=c,c++,java,go,d,fortran,objc,obj-c++
--prefix=/usr
--program-suffix=-4.9
--enable-shared
--enable-linker-build-id
--libexecdir=/usr/lib
--without-included-gettext
--enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.9
--libdir=/usr/lib
--enable-nls
--with-sysroot=/
--enable-clocale=gnu
--enable-libstdcxx-debug
--enable-libstdcxx-time=yes
--enable-gnu-unique-object
--disable-vtable-verify
--enable-plugin
--with-system-zlib
--disable-browser-plugin
--enable-java-awt=gtk
--enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre
--enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64
--with-arch-directory=amd64
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc
--enable-multiarch
--with-arch-32=i586
--with-abi=m64
--with-multilib-list=m32,m64,mx32
--enable-multilib
--with-tune=generic
--enable-checking=release
--build=x86_64-linux-gnu
--host=x86_64-linux-gnu
--target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9.2 (Debian 4.9.2-10)
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/
:/usr/lib/gcc/x86_64-linux-gnu/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/
:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/32/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/
:/lib/../lib32/
:/usr/lib/../lib32/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/
:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../
:/lib/
:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-Wall' '-O2' '-m32' '-fshort-wchar' '-s' '-shared' '-L/usr/local/lib/' '-o' 'samp-redis.so' '-shared-libgcc' '-mtune=generic' '-march=i586'
/usr/lib/gcc/x86_64-linux-gnu/4.9/collect2
-plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
-plugin-opt=-fresolution=/tmp/ccOq8qY8.res
-plugin-opt=-pass-through=-lgcc_s
-plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc_s
--sysroot=/
--build-id
--eh-frame-hdr
-m elf_i386
--hash-style=gnu
-shared
-o samp-redis.so
-s /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/32/crtbeginS.o
-L/usr/local/lib/
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/32
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32
-L/lib/../lib32
-L/usr/lib/../lib32
-L/usr/lib/gcc/x86_64-linux-gnu/4.9
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../..
-Bstatic
--no-undefined
-lcpp_redis amxplugin.o amxplugin2.o main.o
-lstdc++
-lm
-lgcc_s
-lc
-lgcc_s /usr/lib/gcc/x86_64-linux-gnu/4.9/32/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/crtn.o
/usr/bin/ld: cannot find
-lgcc_s
/usr/bin/ld: cannot find
-lgcc_s
collect2: error: ld returned 1 exit status
makefile:15: recipe for target 'build' failed
make: *** [build] Error 1
Apparently it can't find gcc_s
whatever that is? 显然
gcc_s
都找不到gcc_s
? s=static? s =静态?
I tried searching for gcc libs: 我尝试搜索gcc库:
$ find /usr/ -name libgcc*
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc_s.so
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc_eh.a
/usr/lib/gcc/x86_64-linux-gnu/4.9/x32/libgcc_s.so
/usr/lib/gcc/x86_64-linux-gnu/4.9/x32/libgcc_eh.a
/usr/lib/gcc/x86_64-linux-gnu/4.9/x32/libgcc.a
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc.a
/usr/lib/gcc/x86_64-linux-gnu/4.9/32/libgcc_s.so
/usr/lib/gcc/x86_64-linux-gnu/4.9/32/libgcc_eh.a
/usr/lib/gcc/x86_64-linux-gnu/4.9/32/libgcc.a
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc_s_32.so
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc_s_x32.so
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_s.so
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_eh.a
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.a
/usr/lib/x86_64-linux-gnu/libgccpp.so.1
/usr/lib/x86_64-linux-gnu/libgccpp.so.1.0.3
Yet doing a ldconfig search shows files named libgcc.so.1
: 但是,执行ldconfig搜索会显示名为
libgcc.so.1
文件:
$ sudo /sbin/ldconfig -p | grep libgcc
libgccpp.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libgccpp.so.1
libgcc_s.so.1 (libc6,x32) => /usr/libx32/libgcc_s.so.1
libgcc_s.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (libc6) => /usr/lib32/libgcc_s.so.1
Could this be the reason? 这可能是原因吗?
And googling the error brings up some results so I'll keep digging... 谷歌搜索错误带来了一些结果,所以我会继续挖掘...
Even if you build cpp_redis as static library for it to be linkable with shared library it must be compiled with -fPIC flag ie code must be relocatable. 即使将cpp_redis构建为静态库以使其可与共享库链接,也必须使用-fPIC标志对其进行编译,即代码必须可重定位。 Looks like in your case linker silently ignores incompatible code when linking shared lib.
在您的情况下,链接器在链接共享库时会默默地忽略不兼容的代码。 You can check if symbols from cpp_redis resolved into your plugin by running nm with your .so file.
您可以通过使用.so文件运行nm来检查cpp_redis中的符号是否解析为插件。
According to your update, you should link your plugin with -W,--no-undefined
not cpp_redis. 根据您的更新,您应该将插件与
-W,--no-undefined
-no -W,--no-undefined
not cpp_redis链接。 Most probably it will fail as symbols from host program would be missing. 很有可能它将失败,因为主机程序中的符号将丢失。 But you can check if symbols from cpp_redis are listed as missing or not.
但是,您可以检查cpp_redis中的符号是否被列出为缺少符号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.