静态初始化期间的死锁
Deadlock during static initialization
我 运行 在 Solaris 的静态初始化过程中陷入僵局。这种情况与 this user's problem.
非常相似
我的环境是:
- 索拉里斯 10
- gcc 5.4 安装到非标准位置
- 所有相关共享库都link针对来自该安装的 libstdc++ and/or libgcc_s 库
- 提升 1.45(我们很快就会远离它,但目前无法改变)
- 我在 link 动态 或 静态针对 boost 库
时看到这个问题
症状:
- 执行时出现死锁
boost::system::generic_category()
正在调用 generic_category()
来初始化 boost/system/error_code.hpp
中的全局静态引用
- 如果我打乱 link 顺序,将 -lboost_system 放在其他库 link 之前,问题就会消失。
- 如果我在
generic_category()
中设置断点,然后在第一次命中断点后尝试跨过第一行,当在不同共享库的 _init()
——也就是说,从我告诉它越过第一行开始,它就永远不会停在 generic_category()
的第二行。
由于跨过第一行没有用,所以我跨了进去,然后又跨了出去,断点又被击中了。
我重新启动了进程并在遇到断点后介入然后开始步进。跳过对 boost::system::error_category::error_category()
的调用,我 运行 遇到了同样的问题。
我又试了一次,这次是在我到达 error_category()
调用时步进指令。它试图通过调用 elf_rtbndr()
的 PLT 调用它,它应该 return %o0
中的真实函数地址,但是当我再次跨过对 elf_rtbndr()
的调用时命中断点而不是从中断处继续。
当第 2 次遇到断点时,它会在其他一些共享库的 _init()
中调用 generic_category()
;那就是死锁发生的时候。
提前感谢您的宝贵时间和帮助。
这已被报告多次(参见 this post in Boost and another in GCC)。这似乎是 Boost 初始化期间的循环依赖问题,出于某种原因,它只在 Solaris 上出现。通常的建议是通过搞乱库初始化来解决这个问题(例如,像使用 -lboost_system
那样打乱库顺序)。
另一种选择是禁用线程安全保护(-fno-threadsafe-statics
标志),这将消除死锁,但会保留错误的嵌套构造函数调用,这是不可取的。
我 运行 在 Solaris 的静态初始化过程中陷入僵局。这种情况与 this user's problem.
非常相似我的环境是:
- 索拉里斯 10
- gcc 5.4 安装到非标准位置
- 所有相关共享库都link针对来自该安装的 libstdc++ and/or libgcc_s 库
- 提升 1.45(我们很快就会远离它,但目前无法改变)
- 我在 link 动态 或 静态针对 boost 库 时看到这个问题
症状:
- 执行时出现死锁
boost::system::generic_category()
正在调用 generic_category()
来初始化boost/system/error_code.hpp
中的全局静态引用
- 如果我打乱 link 顺序,将 -lboost_system 放在其他库 link 之前,问题就会消失。
- 如果我在
generic_category()
中设置断点,然后在第一次命中断点后尝试跨过第一行,当在不同共享库的_init()
——也就是说,从我告诉它越过第一行开始,它就永远不会停在generic_category()
的第二行。
由于跨过第一行没有用,所以我跨了进去,然后又跨了出去,断点又被击中了。
我重新启动了进程并在遇到断点后介入然后开始步进。跳过对 boost::system::error_category::error_category()
的调用,我 运行 遇到了同样的问题。
我又试了一次,这次是在我到达 error_category()
调用时步进指令。它试图通过调用 elf_rtbndr()
的 PLT 调用它,它应该 return %o0
中的真实函数地址,但是当我再次跨过对 elf_rtbndr()
的调用时命中断点而不是从中断处继续。
当第 2 次遇到断点时,它会在其他一些共享库的 _init()
中调用 generic_category()
;那就是死锁发生的时候。
提前感谢您的宝贵时间和帮助。
这已被报告多次(参见 this post in Boost and another in GCC)。这似乎是 Boost 初始化期间的循环依赖问题,出于某种原因,它只在 Solaris 上出现。通常的建议是通过搞乱库初始化来解决这个问题(例如,像使用 -lboost_system
那样打乱库顺序)。
另一种选择是禁用线程安全保护(-fno-threadsafe-statics
标志),这将消除死锁,但会保留错误的嵌套构造函数调用,这是不可取的。