使用相同库的多个版本时的符号解析

时间:2017-09-05 11:03:53

标签: c++ c libcurl ld name-conflict

我有一个solaris共享对象(common.so文件),它作为第三方应用程序(app.exe)的一部分运行。我无权访问应用程序的源代码。为此,我需要添加发布http请求的功能。我的计划是使用libcurl和openssl。棘手的部分是app.exe已经依赖于旧版本的curl(7.14),它不支持带有tls v1.2的ssl。

我下载了源代码并构建了curl(7.55.1)和openssl .a文件。我还能够使用静态依赖于这些存档文件来构建common.so。 ldd不显示对curl或ssl .so文件的依赖,也不报告任何“未找到符号”错误。

有了这个结果,我希望调用我的curl版本,当它作为应用程序的一部分运行时却没有。相反,curl_version()显示旧版本,我得到错误未知的ssl协议错误

我正在使用solaris studio编译器。应用程序不直接依赖于curl库,而是依赖于一个不同的.so文件,该文件导出与curl同名的符号。我从nm实现了,我假设这个.so文件还静态链接curl。

1 个答案:

答案 0 :(得分:0)

当app.exe加载有问题的两个SO时,它会将每个函数添加到其符号表中。现在必须的两种可能情况中的一种(实际上是OS详细信息,但这里不相关......):

  1. 较新版本在旧版本之前加载,较旧版本会覆盖较新版本。
  2. 较新版本在旧版本之后加载,由于表格中已有条目,因此不再更新。
  3. 现在最干净的解决方案 - 如果适用的话,我。即如果您有权访问源 - 将更新其他SO以使用更新版本的curl。如果这样做,请考虑将curl创建为新的SO而不是将其静态链接到common.so和其他SO中。

    否则,要直接解决问题,您必须切换应用程序加载SO的顺序,这可能意味着反编译app.exe并使用SO更改的链接顺序重建它。问题是:当时可能有两个版本的app.exe,你必须确保只有正确的版本与你的common.so一起分发。潜在的麻烦来源......

    除此之外,我能想到的最好的解决方法是:

    您可以将curl前缀从curl_修改为e。 G。 curl_755_。不要手动尝试这个,但是,你最有可能会这样疯狂...使用脚本(例如perl或python)代替。如果您更新了卷曲源,您可以再次运行它,然后......

    版本更快,但可能不安全:只需更换任何出现的版本。更安全:在第一次运行中识别外部可见的函数(可能还有全局对象)并将它们保存在映射中,然后将映射中包含的字符串的任何出现替换为相应的值。

    后一种方法(map)还允许在以下形式的头文件中生成宏:

    #define curl_xyz curl_755_xyz
    

    这些宏允许common.so的来源看起来好像使用了卷曲的原始来源......