【问题标题】:Relocation error with libstdc++.so.6libstdc++.so.6 的重定位错误
【发布时间】:2015-11-18 15:21:42
【问题描述】:

我的任务是使用 gcc 将一组封闭源代码库从 Windows/MSVC2013 移植到 Ubuntu Linux 12.04/64。我已经编译并安装了 gcc5.2(需要“官方”C++11 支持),它也用 libstdc++.so.6.0.21 替换了 libstdc++ 库。

我的库使用 - 其中包括 - 很棒的 log4cplus 日志框架。这是我要移植的第一部分,我已经成功了:

  • 构建log4cplus共享库
  • 将 log4cplus 共享库部署到 /usr/local/lib 并运行 sudo ldconfig
  • 构建依赖于 log4cplus 的静态库(基本上是在 log4cplus 周围添加了一些语法糖)
  • 构建测试应用程序并将其链接到静态库

当我使用 g++ 的 -static-libstdc++ 编译器选项来编译 log4cplus 时,我的测试应用程序启动并且工作正常。但是,这不是最终的解决方案(封闭源代码)。当我在 log4cplus makefile 中省略该选项时,运行我的应用程序时出现以下错误:

BasicsTests: relocation error: /usr/local/lib/liblog4cplusU.so.0: symbol _ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev, version GLIBCXX_3.4.21 not defined in file libstdc++.so.6 with link time reference 

我已经使用 readelf 工具来确定这个符号是否真的丢失/错误的版本,但显然情况并非如此:

$ readelf -s --wide /usr/local/lib64/libstdc++.so.6 | grep _ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev
  4858: 000000000010cd10   108 FUNC    WEAK   DEFAULT   11 _ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
  6042: 000000000010cd10   108 FUNC    WEAK   DEFAULT   11 _ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev

我的测试应用程序是一个 64 位的可执行文件,所以我希望它链接到那个库:

$ file BasicsTests 
BasicsTests: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, not stripped

我不确定重定位的目标是哪个特定的 so 库(我在系统上有其他 libstdc++ 版本,但没有一个版本早于 6.0.19,而且它们位于我怀疑是特定于应用程序的目录中) .

echo $LD_LIBRARY_PATH 

什么也没给我,所以除了标准之外没有其他路径应该适用

除了我无法解释的错误之外,令我困惑的是没有(链接到)libstdc++.so 位于 /usr/lib 或 /usr/local/lib 中,但是,似乎找到了该库(当找不到库时,我会看到不同的错误)。

如果我问了愚蠢的问题/犯了愚蠢的错误,我深表歉意,但我是 Linux 下的开发新手,这次调查是我过去几天开始进入该领域时令人沮丧的结果。

任何帮助将不胜感激!

编辑 - Oleksandr Kravchuk 提出的问题

/etc/ld.so.conf.d/libc.conf 内容:

# libc default configuration
/usr/local/lib

【问题讨论】:

    标签: c++ linux ubuntu gcc libstdc++


    【解决方案1】:

    似乎问题在于您将二进制文件与一个 libstdc++ 链接,而 Linux 的动态链接器使用另一个。这就是静态链接使您的程序正常工作的原因。

    您可以通过在 /etc/ld.so.conf.d/libc.conf 中注释掉不必要的库副本并运行 ldconfig afterwords 来修复它。

    【讨论】:

    • 非常感谢,但它只有两行:# libc 默认配置 /usr/local/lib,请参阅上面的编辑。但我很欣赏这个提示。也许我错过了 ld 配置文件。但是通过 /etc/ld.so.conf.d/ 中的所有文件对 libstdc++ 进行 grep-ing 并没有显示任何结果。将对此进行深入研究
    • @kritzel_sw 完全正确!但是您正在使用位于 /usr/local/lib64/ 中的那个进行编译
    • @kritzel_sw 检查这是否是问题,运行以下命令export LD_LIBRARY_PATH=/usr/local/lib64/ ./you_bin_file
    • 不确定我是否明白你的意思。 /usr/local/lib64 中的那个似乎是正确的,我在 /usr/local/lib 中没有 lib 或符号链接。 /usr/local/lib 中唯一的库是我自己的 log4cplus 库...
    • 太棒了!有用!非常感谢!我今天刚刚注册,所以我不能投票给你的帖子,但我会尽快回来做。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    相关资源
    最近更新 更多