dlopen第二次在ubuntu 11.04上的坏共享库上工作;在centos 5.5上做正确的事情

dlopen第二次在ubuntu 11.04上的坏共享库上工作;在centos 5.5上做正确的事情,ubuntu,tcl,centos,glibc,dlopen,Ubuntu,Tcl,Centos,Glibc,Dlopen,我有坏的共享库(未定义的符号) 当我第一次对其调用dlopen()时,我从dlerror()得到一个带有正确错误消息的空结果 如果忽略错误消息并使用相同的参数调用dlopen(),则第二次会得到一个非空句柄(这表示库已成功加载)。这显然是错误的 这个问题发生在Ubuntu11.04下(IIRC,10.10没有这个问题)。Centos 5.5没有出现这个问题 特别是,这个问题发生在Tcl解释器中。它将尝试加载一个共享库,首先使用规范化的绝对路径,如果再次失败,则使用用户提供的确切路径字符串。在我的

我有坏的共享库(未定义的符号)

当我第一次对其调用dlopen()时,我从dlerror()得到一个带有正确错误消息的空结果

如果忽略错误消息并使用相同的参数调用dlopen(),则第二次会得到一个非空句柄(这表示库已成功加载)。这显然是错误的

这个问题发生在Ubuntu11.04下(IIRC,10.10没有这个问题)。Centos 5.5没有出现这个问题

特别是,这个问题发生在Tcl解释器中。它将尝试加载一个共享库,首先使用规范化的绝对路径,如果再次失败,则使用用户提供的确切路径字符串。在我的例子中,两者都应该失败,但是在Ubuntu 11.04下,第二个调用错误地成功了

奇怪的是,我只能用我确切的产品共享库重现这个问题。如果我制作了一个精简的共享库,那么它工作正常

这样的程序足以显示我的产品库的问题:

#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);
}
#包括
#包括
int main()
{
void*h;
h=dlopen(“./prod.so”,RTLD_NOW | RTLD_LOCAL);
printf(“h是%p\n”,h);
printf(“err为%s\n”,dlerror());
h=dlopen(“./prod.so”,RTLD_NOW | RTLD_LOCAL);
printf(“h是%p\n”,h);
}

有一段时间,我偶尔会看到这个问题的边缘,但我还没有确定到底是什么原因导致了它(我还没有找到适合谷歌的东西,但Ubuntu认为这不是一个标题变化,所以很难找到)。有人在传递IRC时向我提到了问题所在,但那是在不久前,当时我正忙着解决另一个问题,我没有保存足够的信息(写下来或存储在内存中)来重建它。这是我最好的回忆

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

简言之,这是某人的错误,但我不知道是谁的错误。很多(但不是全部!)Linux发行商并不擅长向上游反馈他们发现或创建的问题


注意:如果上面的代码是Tcl的
load
命令的代理,请注意这是一个。

我讨厌它没有告诉您哪个符号是未定义的。这对追查这些东西很有帮助!是的,我觉得这很复杂,但我希望专家们知道。:)感谢您抽出时间回答。