gpt4 book ai didi

c++ - `dlopen` 'ing a .so 包含符号导致 undefined symbol

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:40:30 27 4
gpt4 key购买 nike

问题

具体来说,我正在为我的应用程序使用 cblas。我创建了一个使用 cblas 作为子例程的 foo.so,并且我 dlopen('foo.so', RTLD_LAZY)

这是我用来编译的标志(编辑了一些 -I 标志):

g++-8 -std=c++17 -shared -O3 -xc++ 
-ffast-math -fPIC -fopenmp -lcblas - -o /mnt/xxx/python/test.so

这是我在 dlopen() 上遇到的错误:

test.so: undefined symbol: cblas_dgemm

这里我们看到 cblas_dgemm 包含在 .so 中。

root@cd872c4b85ff:/mnt/xxx/python# objdump -TC test.so | grep cblas
0000000000000000 D *UND* 0000000000000000 cblas_ddot
0000000000000000 D *UND* 0000000000000000 cblas_dsyrk
0000000000000000 D *UND* 0000000000000000 cblas_dgemm
0000000000000000 D *UND* 0000000000000000 cblas_dgemv

但是在 ldd 中它没有被列为依赖项。

root@cd872c4b85ff:/mnt/xxx/python# ldd test.so
linux-vdso.so.1 (0x00007ffdbb3c4000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f43f23a7000)
libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f43f2177000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f43f1f5f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f43f1b6e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f43f17d0000)
/lib64/ld-linux-x86-64.so.2 (0x0000562eb733a000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f43f15cc000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f43f13ab000)

我做了一个测试编译,它说 -lcblas 已成功找到:

g++-8 -lcblas -Wl,--verbose | grep blas
attempt to open /usr/lib/gcc/x86_64-linux-gnu/8/libcblas.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/8/libcblas.a failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/libcblas.so succeeded
-lcblas (/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/libcblas.so)
/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status

什么起作用

一件重要的事情是,如果我为 LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libcblas.so 设置我的环境变量,可执行文件将正确运行。但是,这显然不是使可执行文件工作的正确方法。 -Wl,rpath= 也不是正确的方法,因为 cblas 将驻留在不同的目录中(即在 OS X 上它位于 /usr/lib/libcblas.so 中,并且在 ubuntu 中是 /usr/lib/x86_64-linux-gnu/libcblas.so,我猜会有更多不可预测的位置。

可能是什么原因?我没有正确链接它吗?动态链接器是否出于某种原因找不到符号?

由于部分信息已编辑,如果有任何需要,请告诉我,我会将其添加到上面的信息中。谢谢。

编辑:符号确实存在于 libcblas.so 中:

root@3841c2760800:/usr/lib/x86_64-linux-gnu# nm -D libcblas.so | grep cblas_ddot
000000000000a0a0 T cblas_ddot
root@3841c2760800:/usr/lib/x86_64-linux-gnu# nm -D libcblas.so | grep cblas_dgemm
0000000000005790 T cblas_dgemm
root@3841c2760800:/usr/lib/x86_64-linux-gnu# nm -D libcblas.so | grep cblas_dgemv
00000000000077f0 T cblas_dgemv
root@3841c2760800:/usr/lib/x86_64-linux-gnu# nm -D libcblas.so | grep cblas_dsyrk
00000000000065f0 T cblas_dsyrk

编辑:

依存关系图,我相信,看起来像这样:

main --(dlopens)--> test.so 
--(includes)--> header-only linear algebra library
--(calls cblas subroutine)--> /usr/lib/x86.../libcblas.so

最佳答案

所以 - 这是因为我的链接的顺序。我所做的是将 C++ 文件(或字符串)流式传输到这个 g++ 编译过程中。要流式传输,可以这样做:

g++ ... -xc++ - ...

-xc++ 告诉 g++ 它正在接受一个 c++ 文件(强制),而 - 是文件字符串的占位符。在我的汇编中,我有:

g++ ... linker_flags ...  -xc++ -

这意味着它实际上没有正确链接(linker_flags 需要在文件名之后)。

我知道顺序很重要,但在这种情况下,当我在文件中流式传输时,我忘记了这个原则,这就是符号未定义的原因。

关于c++ - `dlopen` 'ing a .so 包含符号导致 undefined symbol ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51996751/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com