2009-08-14 90 views
1

在Solaris 9和10,x86和SPARC,我們有一個被退出時掛的過程:Solaris進程掛在退出

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。

有問題的進程是一個來自多線程父代的單線程子代,但不是exec ed。

有沒有人見過類似的東西?

你知道是否有更新版本的gcc可以解決這個問題嗎?

回答

2

您可以嘗試撥打_exit()退出子進程,而不是exit()。 exit()是一個庫函數,它在退出之前執行各種形式的庫清除 - 例如,它將stdio緩衝區刷新到磁盤。 _exit()是終止進程的實際系統調用。即使在單線程程序中,您通常在分叉的子內部使用_exit()來防止庫清除發生兩次。

+0

好主意 - 我已將代碼段中的所有退出調用更改爲_exit。 – 2009-08-25 12:30:33

+0

官方的Single UNIX規範聲明在fork()之後使用_exit()而不是exit() - http://www.opengroup.org/pubs/online/7908799/xsh/vfork.html – 2009-10-05 09:53:06

1

這正是爲什麼你應該總是在分叉MT進程之後執行exec操作:你不知道什麼會鎖定父進程中的其他線程,以及何時需要這些鎖之一。這裏你需要一個退出,但你不能得到它,因爲鎖定它的線程不存在於子中。

GCC的新版本有點不太可能幫助你。即使它確實有幫助,打這樣的另一個鎖只是一個時間問題。

在創建第一個線程之前fork,或者在fork之後立即執行exec。這些確實是唯一明智的選擇。

+0

我認爲你是對的 - 我已經改變了運行/ bin/true而不是正常退出的通用路徑 - 當然如果execl()失敗仍然有問題。 – 2009-08-25 12:30:02