2

我正在尝试创建一个“调试”共享库(即 .so 或 .dll 文件),它调用另一个与调试库具有相同 C API 的“真实”共享库(在这种情况下,模拟 PKCS# 11 API)。但是,我遇到了调试库的链接映射与真实库的链接映射冲突并导致调试库调用自己的函数而不是真实库中的相应函数的麻烦。我通过使用 POSIX dlmopen 命令找到了解决此问题的方法,但想了解是否可以使用 GNU 的 libtool。

在我的 Solaris 10 系统上,当测试应用程序静态链接到调试库时,以下代码使断言失败:

#include <dlfcn.h>
int MyFunctionName() {
  int (*function_ptr)();
  void *handle = dlopen("realsharedlibrary.so", RTDL_LAZY);
  *(void **)(&function_ptr) = dlsym(handle, "MyFunctionName");
  ASSERT(function_ptr != MyFunctionName); // Fails
  return (*function_ptr)();
}

在这种情况下,我得到一个指向本地“MyFunctionName”(在调试库中)的函数指针,而不是真正共享库中的 MyFunctionName。

我发现可以通过使用命令“dlmopen”而不是“dlopen”来解决这个问题,并告诉 dlmopenLM_ID_NEWLM在加载真实库时创建一个新的链接映射(带有参数):

int MyFunctionName() {
  int (*function_ptr)();
  void *handle = dlmopen(LM_ID_NEWLM, "realsharedlibrary.so", RTDL_LAZY);
  *(void **)(&function_ptr) = dlsym(handle, "MyFunctionName");
  ASSERT(function_ptr != MyFunctionName); // succeeds
  return function_ptr(); // call real function
}

不幸的是,dlmopen 似乎没有包含在 libtool 中(即,我在 libtool 中没有看到 lt_dlmopen 函数)。

是否可以使用 libtool 命令做同样的事情——也就是说,在加载新库时创建一个新的链接映射,这样它就不会与调试库的链接映射冲突?

4

1 回答 1

1

我还没有找到使用 libtool 解决这个问题的好方法,但是有一种方法可以通过使用带有这些标志的 dlopen 来避免特定于 Solaris 的“dlmopen”函数:

void *handle = dlopen("realsharedlibrary.so", RTLD_NOW | RTLD_GROUP | RTLD_LOCAL)

显然,符号冲突的问题是通过使用RTLD_NOW而不是RTLD_LAZY和添加来解决的RTLD_GROUP。之所以RTLD_LOCAL存在,是因为 POSIX 需要使用RTLD_LOCALor RTLD_GLOBAL,或者行为未定义。对于 Solaris,行为默认为RTLD_LOCAL.

不过,悬而未决的问题是,是否可以将这些类型的标志传递给 lt_dlopen。

于 2009-12-03T18:06:06.720 回答