【问题标题】:Solaris process hanging in exitSolaris 进程在退出时挂起
【发布时间】:2009-08-14 10:28:05
【问题描述】:

在 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

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

有问题的进程是来自多线程父级forked 但不是execed 的单线程子级。

有人见过类似的吗?

你知道更新版本的 gcc 是否能解决这个问题吗?

【问题讨论】:

    标签: gcc solaris


    【解决方案1】:

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

    【讨论】:

    【解决方案2】:

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

    新版本的 GCC 不太可能对您有所帮助。即使它确实有帮助,但像这样击中另一个锁只是时间问题。

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

    【讨论】:

    • 我认为你是对的——我已经改变了运行 /bin/true 的通用路径而不是正常退出——当然如果 execl() 失败仍然有问题。
    猜你喜欢
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    相关资源
    最近更新 更多