Linux
Linux 程序可以攔截發送給其子程序的信號嗎?
我有一個圍繞大型執行檔的外殼包裝器。它做這樣的事情:
run/the/real/executable "$@" & PID=$! # perform # a few # minor things wait $PID # perform some # post-processing
它之後做的一件事
wait
是檢查核心轉儲並處理程序崩潰,但是,到那時該程序已經死了並且一些資訊不再可用。致命信號 (
SIGSEGV
或SIGBUS
) 是否可以在傳遞給子程序之前被 shell 腳本攔截?然後,例如,我可以執行
lsof -p $PID
以獲取包裝程序在它死之前打開的文件列表……更新:我嘗試使用
strace
來擷取接收信號的程序。不幸的是,似乎有一場比賽——當strace
報告孩子的信號時,孩子正在出去,不知道是否lsof
會得到它的文件列表……這是測試腳本,它生成
/bin/sleep
並嘗試獲取它已打開用於寫入的文件。有時/tmp/sleep-output.txt
報告應該是,有時列表是空的……ulimit -c 0 /bin/sleep 15 > /tmp/sleep-output.txt & NPID=$! echo "Me: $$, sleep: $NPID" (sleep 3; kill -BUS $NPID) & ps -ww $NPID while read line do set -x outputfiles=$(lsof -F an -b -w -p $NPID | sed -n '/^aw$/ {n; s,.,,; p}') ps -ww $NPID lsof -F an -b -w -p $NPID break done < <(strace -qq -p $NPID -e trace=signal 2>&1) echo $outputfiles wait $NPID
上述測試需要使用
ksh
orbash
(為了使< <(...)
構造工作)。
據我所知,沒有 shell 方法可以做你正在嘗試的事情,它必須通過自定義程序來完成。
用於
ptrace()
監視程序,類似於調試器的方式。當程序接收到信號時,它會停止,並通知監控程序(它的呼叫wait()
將返回,並且WIFSTOPPED(status)
為真)。然後它可以執行
lsof -p <pid>
以列出程序的打開文件,然後呼叫ptrace(PTRACE_CONT, pid, NULL, 0)
以重新啟動程序。