Gcc 静态初始化期间的死锁

Gcc 静态初始化期间的死锁,gcc,boost,solaris,Gcc,Boost,Solaris,在Solaris中进行静态初始化时,我遇到了死锁。这种情况与美国极为相似 我的环境是: solaris 10 gcc 5.4安装在非标准位置 所有相关的共享库都链接到该安装中的libstdc++和/或libgcc_库 增压1.45(我们很快就会远离它,但目前这一点无法改变) 当动态或静态链接boost库时,我看到了这个问题 症状: 执行时死锁boost::system::generic_category() 正在调用generic\u category()来初始化boost/system/

在Solaris中进行静态初始化时,我遇到了死锁。这种情况与美国极为相似

我的环境是:

  • solaris 10
  • gcc 5.4安装在非标准位置
  • 所有相关的共享库都链接到该安装中的libstdc++和/或libgcc_库
  • 增压1.45(我们很快就会远离它,但目前这一点无法改变)
  • 当动态或静态链接boost库时,我看到了这个问题
症状:

  • 执行时死锁
    boost::system::generic_category()
  • 正在调用
    generic\u category()
    来初始化
    boost/system/error\u code.hpp中的全局静态引用
  • 如果我改变链接顺序,将-lboost_系统放在链接到的其他库之前,问题就会消失
  • 如果我在
    generic\u category()
    中设置了一个断点,然后在第一次命中断点后尝试跨过第一行,那么当在不同共享库的
    \u init()
    中执行相同的函数时,断点会再次命中——也就是说,它永远不会停在
    generic\u category()的第二行
    从我告诉它跨过第一行开始
由于跨过第1行不起作用,我跨进第1行,然后走出&断点再次被击中

我重新启动了进程&在断点被击中后介入,然后开始介入。在调用
boost::system::error\u category::error\u category()
时,我遇到了相同的问题

我再试了一次,这一次在调用
error\u category()
时执行指令。它试图通过PLT调用它,PLT调用
elf_rtbndr()
,该函数应该返回
%o0
中实际函数的地址,但当我跨过调用
elf_rtbndr()
时,它再次命中断点,而不是继续它停止的位置

当断点第二次被命中时,它正在调用其他共享库的
\u init()
中的
generic\u category()
;这就是死锁发生的时候


提前感谢您的时间和帮助。

这已被报道多次(请参阅和)。这似乎是Boost初始化期间的循环依赖性问题,出于某种原因,Boost初始化只在Solaris上显示。通常的建议是通过干扰库初始化来解决此问题(例如,通过像处理
-lboost\u系统那样洗牌库顺序)


另一个选项是禁用线程安全防护(
-fno threadsafe statics
标志),这将消除死锁,但会保留错误的嵌套构造函数调用,这是不可取的。

这已被报告多次(请参阅和)。这似乎是Boost初始化期间的循环依赖性问题,出于某种原因,Boost初始化只在Solaris上显示。通常的建议是通过干扰库初始化来解决此问题(例如,通过像处理
-lboost\u系统那样洗牌库顺序)


另一个选项是禁用线程安全防护(
-fno threadsafe statics
标志),这将消除死锁,但会保留错误嵌套的构造函数调用,这是不可取的。

我建议报告一个错误以提升,这听起来真的像是实现中的一个bug。我打赌它已经在更新版本的boost中修复了。我们多年来一直在使用Sun Studio。让我们的代码用Sun Studio的最新版本(据说是与gcc兼容的)进行构建将被证明是令人恼火的(除其他外,假装是gcc来愚弄boost中的
#ifdef
宏的挑战还不够好),所以我们将放弃对sun studio的支持,然后跳转到更新版本的boost;但同时…我建议报告一个bug到Boost,这听起来真的像是实现中的一个bug。我打赌它已经在更新版本的Boost中修复了。我们多年来一直在使用Sun Studio。让我们的代码用Sun Studio的最新版本(据说是与gcc兼容的)进行构建将被证明是令人恼火的(除其他外,假装是gcc来愚弄boost中的
#ifdef
宏的挑战还不够好),所以我们将放弃对sun studio的支持,然后跳转到更新版本的boost;但与此同时。。。