【发布时间】:2023-03-19 13:32:01
【问题描述】:
我已经构建了一个共享库 (OpenSSL) 的调试版本,因此我可以使用调试器逐步执行某个函数,以更好地了解正在发生的事情。
但是,我很难真正链接到我构建的调试版本。出于某种原因,无论我做什么,链接器总是最终链接到预安装的系统版本,即使两个版本都在 usr/lib 目录中,软链接设置正确(AFAIK),我明确编译时在命令行指定调试库。
所以共享库的原始(系统安装)版本是:
>ls /usr/lib/x86_64-linux-gnu/ -lh | grep libssl
lrwxrwxrwx 1 root root 15 Sep 23 2016 libssl.so -> libssl.so.1.0.0
-rw-r--r-- 1 root root 386K Sep 23 2016 libssl.so.1.0.0
我从源代码编译并配置为共享库(对所有目标文件使用 fPIC 标志)的调试版本是:
>ls /usr/lib/ -lh | grep libssl
lrwxrwxrwx 1 root root 29 Oct 19 11:31 libssldebug.so -> /usr/lib/libssldebug.so.1.0.2
-rwxr-xr-x 1 root root 2.3M Oct 19 00:53 libssldebug.so.1.0.2
其他 OpenSSL 共享库 libcrypto 也是如此。我在/usr/lib 中有一个 libcryptodebug.so.1.0.2 和一个相应的软链接。
所以,我尝试构建一个可执行文件并链接到调试共享库,如下所示:
>g++ test.cpp -o test -std=c++14 -lssldebug -lcryptodebug -I openssl-1.0.2p/include/
它编译和链接没有错误。
还有……当我使用ldd 检查可执行文件时,我看到了:
>ldd test
linux-vdso.so.1 (0x00007ffcaa39b000)
libssl.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007ff717d37000)
libcrypto.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007ff71793b000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff717630000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff71732f000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff717119000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff716d6e000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff716b6a000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff717f98000)
因此,即使我明确地与-lssldebug 链接,并且它编译和链接时没有错误,ldd 仍然显示链接器由于某种原因正在与非调试版本 (/usr/lib/x86_64-linux-gnu/libssl.so.1.0.0) 链接。我也尝试运行ldconfig,然后重新编译/链接,但它仍然与旧(非调试)版本链接。
那么这里发生了什么?我做错了什么导致它默默地忽略命令行链接器参数并以某种方式默认使用非调试版本(它具有完全不同共享库名称!)不知何故?
【问题讨论】:
-
我不认为你做错了什么。当您链接到共享库时,它已嵌入其名称中,称为 SONAME。对于 openssl,它的调试版本和常规版本似乎具有相同的 SONAME - 这就是将在运行时加载的内容。即构建可执行文件时指定的文件名不是运行时使用的文件名。运行时链接器只会在其搜索路径中选择与它在构建时找到的 SONAME 匹配的第一个文件。
标签: c++ gcc linker shared-libraries linker-errors