【发布时间】:2016-02-03 12:38:26
【问题描述】:
我正在使用一个有很多全局变量的共享库, 几乎用在 所有导出的函数,因此库函数不是线程安全的。 我的应用程序创建了多个线程,每个线程动态地打开它 库并避免在并行调用之间使用任何同步 对出口 函数,我在磁盘上多次复制了具有不同名称的库 每个线程都打开自己的副本。为避免这种情况,现在我希望改用 dlmopen,但我遇到了一个问题。
当我在应用程序中使用 dlopen 打开库时,应用程序运行正常
libHandle = dlopen(ip->pathname, (RTLD_LAZY |RTLD_LOCAL|RTLD_DEEPBIND|RTLD_NODELETE));
当我在应用程序中使用 dlmopen 时,出现错误:
ip->libHandle = dlmopen(LM_ID_NEWLM, ip->pathname,
(RTLD_LAZY |RTLD_LOCAL|RTLD_DEEPBIND|RTLD_NODELETE));
dlerror 是:
error(libfoo.so.0: undefined symbol: _ZTIN6google8protobuf11MessageLiteE)
执行 nm 确实显示符号未定义 U _ZTIN6google8protobuf11MessageLiteE
问题1:我想知道如何解决这个问题,以便我可以使用 dlmopen。
原因是当使用 LM_ID_NEWLM 时,会在 libc 中创建一个没有任何符号的新的空命名空间。因此,该库应该是自包含的或与任何依赖项重新链接。
问题 2:我的主应用程序导出了一些 libfoo 将使用的符号。由于在新命名空间中打开 libfoo,主应用程序的符号对 libfoo 不可见,因此无法解析它们。 有没有办法告诉链接器创建一个新的命名空间 NEWLM,通过复制现有的基本命名空间,而不是使用新创建的命名空间的 dlmopen + lmid 打开所有其他必需符号已经存在的 libfoo?
问题 3:我可以自己映射 libfoo 的不同部分,并提供一个指向 libc 的映射部分的指针。意味着打开文件并将其从libc中映射出来并让它完成符号解析的工作?这样我根本不需要调用 dlopen 并且多个文本部分的问题将得到解决。
【问题讨论】:
标签: multithreading dll linker dynamic-linking dlopen