dlopen第二次在ubuntu 11.04上的错误共享库上工作;在centos 5.5上做正确的事情 [英] dlopen works second time on bad shared library on ubuntu 11.04; does the right thing on centos 5.5

查看:100
本文介绍了dlopen第二次在ubuntu 11.04上的错误共享库上工作;在centos 5.5上做正确的事情的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的共享库错误(未定义符号)。

I have bad shared library (undefined symbol).

当我第一次对其调用dlopen()时,我收到了来自正确消息的NULL结果dlerror()。

When I call dlopen() on it the first time, I get a NULL result with correct error message from dlerror().

如果我忽略错误消息并使用相同的参数调用dlopen(),则第二次获得非空句柄(这表明库已成功加载)。

If I ignore the error message and call dlopen() using the same arguments, I get a non-null handle the second time (which indicates that the library was successfully loaded). This is obviously wrong.

在Ubuntu 11.04下会发生此问题(IIRC,10.10没有此问题)。 Centos 5.5不会出现此问题。

This problem occurs under Ubuntu 11.04 (IIRC, 10.10 did not have this problem). Centos 5.5 doesn't exhibit this problem.

特别是,此问题发生在Tcl解释器中。它将尝试加载共享库,首先使用规范化的绝对​​路径,如果加载失败,则再次使用用户提供的确切路径字符串从字面上再次失败。就我而言,两者都应该失败,但是第二个调用在Ubuntu 11.04下不能成功执行。

In particular, this problem occurs within the Tcl interpreter. It will try to load a shared library, first with a canonicalized absolute path and if that fails again literally with the exact path string the user gave. In my case, both should fail, but the second call is incorrectly succeeding under Ubuntu 11.04.

奇怪的是,我只能在完全共享生产的情况下重现此问题图书馆。如果我制作了简化的共享库,则它可以正常工作。

Oddly enough, I am able to reproduce this problem only with my exact production shared library. If I make a reduced shared library, it is working correctly.

像这样的程序足以显示生产库中的问题:

A program like this is enough to show the problem with my production library:

#include <stdio.h>
#include <dlfcn.h>

int main()
{
  void* h;

  h = dlopen("./prod.so", RTLD_NOW | RTLD_LOCAL);
  printf("h is %p\n", h);
  printf("err is %s\n", dlerror());
  h = dlopen("./prod.so", RTLD_NOW | RTLD_LOCAL);
  printf("h is %p\n", h);
}


推荐答案

我一直在看偶尔会出现此问题的边缘,但我还没有确切查明是什么原因造成的(我还没有找到适合Google的东西,但是Ubuntu觉得这不是标题变化,所以它是很难找到)。有人在传给IRC时向我提到了问题,但是不久前,当时我正尽全力解决另一个问题,而且我没有保存足够的信息(记下或记入内存)重建它。因此,这是我最好的回忆……

I've been seeing the edges of this issue occasionally for a while, but I've yet to pin down exactly what caused it (I've yet to find the right thing to Google for, but it's not something that Ubuntu feels to be a headline change so it's hard to find). Someone mentioned to me in passing on IRC what was wrong, but it was a while ago, I was up to my eyeballs in another problem at the time, and I didn't save enough information (written down or in memory) to be able to reconstruct it. So this is my best recollection…

据我所知,在构建某些库时使用的链接选项或在构建时使用的默认选项都进行了一些更改解决依赖库,这导致Tcl无法加载其依赖的所有内容。因为它无法加载某些依赖项(甚至可能是依赖项的依赖项),所以它无法加载库的其余部分(由于要使用 RTLD_NOW 标志)然后您到达了现在的位置。它可能很容易修复,例如通过更改链接时选项,但我不知道具体出了什么问题。

As far as I can tell, there were some changes to either the link options used when building some libraries or to the default options used when resolving dependent libraries, and this is causing Tcl to fail to load everything it depends on. Because it fails to load some dependency — or maybe even a dependency of a dependency — it fails to load the rest of the library (because of the RTLD_NOW flag, which you want) and you get to where you are now. It's probably easy to fix, such as by changing link-time options, but I don't know what's wrong in detail.

简而言之,它是某人的错误,但我不知道。许多(但不是全部!)Linux发行商不太擅长反馈他们发现或创建的问题。

In short, it's someone's bug, but whose I don't know. A lot (but not all!) of Linux distributors are not very good at feeding back upstream on issues that they discover or create.

NB:如果上面的代码是Tcl的 load 命令的代理,请注意,这是本身的小区域

NB: if your code above is a proxy for Tcl's load command, be aware that this is a tricky area in itself.

这篇关于dlopen第二次在ubuntu 11.04上的错误共享库上工作;在centos 5.5上做正确的事情的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆