來自

2011-11-10 24 views
1

的信號在哪裏我在solaris服務器上運行了一個shell腳本,它是一個非常複雜的腳本,它會調用一些其他shell或perl腳本,整個執行過程需要很長時間 - 幾個小時。來自

奇怪的是,它總是退出異常。我使用「truss」命令來記錄shell進程的系統調用。它表明原因似乎是信號#15 SIGTERM的到來。但我不知道15號信號從哪裏來?有什麼辦法可以檢測到來自哪個進程的信號?

我的服務器信息:

uname -a 
SunOS zsups379 5.10 Generic_144488-07 sun4u sparc SUNW,Sun-Fire-880 

桁架輸出的切片(23528的主要流程是,25213是23528的子進程):

25213/2:  read(8, "17A6 G8A078A 58E15 P9E 5".., 8192)  = 8192 

25213/1:   Received signal #15, SIGTERM, in lwp_wait() [caught] 

23528:  Received signal #15, SIGTERM, in waitid() [caught] 

25213/2:  write(9, " X #85 f @F5 Z88CAFB J\n".., 515)  = 515 

23528: waitid(P_ALL, 0, 0xFFBFD958, WEXITED|WTRAPPED|WSTOPPED|WCONTINUED) Err#91 ERESTART 

25213/1:  lwp_wait(2, 0xFFBFD39C)       Err#91 ERESTART 

25213/1:  lwp_sigmask(SIG_SETMASK, 0xFFBFFEFF, 0x0000FFF7) = 0xFFBFFEFF [0x0000FFFF] 

23528: lwp_sigmask(SIG_SETMASK, 0x00004000, 0x00000000) = 0xFFBFFEFF [0x0000FFFF] 
.... 

回答

7

可以輕鬆地跟蹤發送給你的過程的所有信號通過使用的dtrace腳本類似於那一個:

proc:::signal-send 
/args[2] == 15/
{ 
    printf("Process %d (%s) killing %d (%s)\n", 
      pid, execname, args[1]->pr_pid, args[1]->pr_fname); 
} 
+0

謝謝。這對我來說是一個新的方向,因爲我從未使用過dtrace,所以我會試一試。 – Arkie

+0

事實上,在Solaris系統上,您會發現'/ usr/demo/dtrace/sig.d'作爲DTrace可以執行的操作的示例。只需嘗試一下。 –

+0

@FrankH:我建議(現在已修復)的腳本針對的是user1038919的信號,並會在發生SIGTERM時立即顯示出來。演示之一是對所有信號進行彙總統計,這當然很有趣,但不太適合啓動調查。 – jlliagre

2

一個與信號問題作爲IPC(進程間通信)的一種方法是無法找出信號來自何處。由於您可能未在truss輸出中看到kill(0, SIGTERM),因此您可以假定該信號不是來自桁架過程。因此,它必須來自其他地方 - 或者(可能,但不太可能)系統本身,或者(更可能)是另一個過程。

我的記憶失敗 - 部分原因是因爲我從來沒有使用的機制...

有在POSIX的sigaction()系統調用與SA_SIGINFO標誌和<signal.h>定義的siginfo_t結構。

<signal.h>頭應確定siginfo_t類型的結構,其中應至少包括以下成員:

int   si_signo Signal number. 
int   si_code Signal code. 
int   si_errno If non-zero, an errno value associated with 
         this signal, as described in <errno.h>. 
pid_t   si_pid Sending process ID. 
uid_t   si_uid Real user ID of sending process. 
void   *si_addr Address of faulting instruction. 
int   si_status Exit value or signal. 
long   si_band Band event for SIGPOLL. 
union sigval si_value Signal value. 
+0

是的,我也注意到siginfo_t類型。事實上,我可以編寫一個信號處理程序來在我的主進程中獲取siginfo_t,如我的示例中的進程23528,並且該信號來自其子25213。但是,如果信號是逐層發佈和傳輸的,例如進程25213不是真正的信號發送器,它只是捕獲其他進程產生的信號。進程25213的源代碼對我來說是不可更改的,所以我不能爲它添加信號處理程序。就這樣,我無法將信號處理程序添加到每個圖層子進程。我如何獲得原始發件人流程? – Arkie