Linux

Linux 程序可以攔截發送給其子程序的信號嗎?

  • June 28, 2018

我有一個圍繞大型執行檔的外殼包裝器。它做這樣的事情:

run/the/real/executable "$@" &
PID=$!
# perform
# a few
# minor things
wait $PID
# perform some
# post-processing

它之後做的一件事wait是檢查核心轉儲並處理程序崩潰,但是,到那時該程序已經死了並且一些資訊不再可用。

致命信號 (SIGSEGVSIGBUS) 是否可以在傳遞給子程序之前被 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

上述測試需要使用kshor bash(為了使< <(...)構造工作)。

據我所知,沒有 shell 方法可以做你正在嘗試的事情,它必須通過自定義程序來完成。

用於ptrace()監視程序,類似於調試器的方式。當程序接收到信號時,它會停止,並通知監控程序(它的呼叫wait()將返回,並且WIFSTOPPED(status)為真)。

然後它可以執行lsof -p <pid>以列出程序的打開文件,然後呼叫ptrace(PTRACE_CONT, pid, NULL, 0)以重新啟動程序。

引用自:https://unix.stackexchange.com/questions/451816