【发布时间】:2014-04-08 13:16:09
【问题描述】:
过去几天我一直在努力解决一个奇怪的问题。我们使用 GCC 4.8 创建了一些库,它们静态链接了它们的一些依赖项——例如。 log4cplus 或提升。对于这些库,我们使用 boost-python 创建了 Python 绑定。
每次这样的库使用 TLS(如 log4cplus 在它的静态初始化中所做的或 stdlibc++ 在抛出异常时所做的 - 不仅在初始化阶段),整个事情都会在段错误中崩溃 - 每次线程局部变量的地址为 0。
我尝试了所有方法,例如重新编译、确保使用 -fPIC、确保使用 -tls-model=global-dynamic 等等。没有成功。然后今天我发现这些崩溃的原因是我们链接 OpenMP 的方式。我们使用“-lgomp”而不是仅仅使用“-fopenmp”来做到这一点。因为我改变了这个一切正常 - 没有崩溃,没有什么。很好!
但我真的很想知道问题的原因是什么。那么这两种在 OpenMP 中链接的可能性有什么区别呢?
我们在这里有一台 CentOS 5 机器,我们在 /opt/local/gcc48 中安装了 GCC-4.8,我们还确定来自 /opt/local/gcc48 的 libgomp 以及来自的 libstdc++ 已被使用那里(使用了 DL_DEBUG)。
有什么想法吗?在 Google 上没有找到任何东西 - 或者我使用了错误的关键字:)
【问题讨论】:
-
-pthread 或 -lpthread 已经存在
-
用
-v编译并比较输出... -
添加 -v 作为链接器选项表明 -fopenmp 在末尾隐式添加了 -lgomp。其他一切都保持不变。如果没有 -fopenp,我有“-lstdc++ -lm -lgcc_s -lpthread -lc -lgcc_s”,而使用 -fopenmp 它变成“-lstdc++ -lm -lgomp -lgcc_s -lpthread -lc -lgcc_s”。我仍然看不到崩溃的原因,因为所有这些库都是动态链接的 :(
-
那么它可能是重要的 -l 标志的顺序。也许 -lgomp 在 -lpthread 或其他一些排列之前很重要。您可以尝试使用 LD_PRELOAD 来查看以不同的顺序加载依赖项是否会产生影响。
-
LD_PRELOADing libgomp.so 确实有效 - 所以在加载有关 TLS 的 OpenMP 时似乎发生了一些有趣的事情......让我们看看我们是否能找出那里到底发生了什么......
标签: c++ openmp static-linking dlopen