Solaris进程在退出时挂起

时间:2009-08-14 10:28:05

标签: gcc solaris

在Solaris 9和10上,x86和Sparc,我们有一个在退出时挂起的进程:

fe0b5994 lwp_park (0, 0, 0)
fe0b206c slow_lock (ff388908, fe080400, 0, 0, 98, fe0abe00) + 58
ff376aa8 __deregister_frame_info_bases (2a518, 1, 0, 2daf0, 0, ff376be4) + 4c
00014858 ???????? (0, ff000000, 0, 0, 0, 0)
00019920 _fini    (0, 0, 210fc, fe21cbf0, 5, fe25897c) + 4
fe21cbf0 _exithandle (fee66a4c, 0, 40, 0, 0, fe2bc000) + 70
fe2a0564 exit     (0, fdefb47c, 40, fdefb8ff, 2c, 0) + 24
fee66a4c (our code) (4e280, 5ab5c, 5aa60, 2ed0, 81010100, fdefb988) + 244

我们的代码使用gcc 3.4.6在Solaris 9机器上编译。

相关流程是来自多线程父级的单线程子级,fork ed但不是exec ed。

有没有人见过类似的东西?

您知道更新版本的gcc是否可以解决问题?

2 个答案:

答案 0 :(得分:2)

您可以尝试调用_exit()退出子进程,而不是exit()。 exit()是一个库函数,它在退出之前执行各种形式的库清理 - 例如,它将stdio缓冲区刷新到磁盘。 _exit()是终止进程的实际系统调用。即使在单线程程序中,您通常在分叉子项中使用_exit()来防止库清理发生两次。

答案 1 :(得分:1)

这正是你应该总是在一个MT进程中执行fork之后执行的原因:你不知道什么锁定父进程中的其他线程,以及何时你可能需要其中一个锁。在这里你需要一个退出,但你无法得到它,因为锁定它的线程在孩子中不存在。

新版GCC有点不太可能帮到你。即使它确实有帮助,你再打这样的锁也只是时间问题。

在创建第一个线程之前进行fork,或者在fork之后立即执行exec。这些确实是唯一明智的选择。