Linux 进程可以拦截发送给其子进程的信号吗?

Linux 进程可以拦截发送给其子进程的信号吗?

我有一个大型可执行文件的外壳包装器。它做了这样的事情:

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

它在之后所做的事情之一wait是检查核心转储并处理进程崩溃,但是,到那时该进程已经死亡并且某些信息不再可用。

shell 脚本可以在将致命信号 (SIGSEGVSIGBUS) 传递给子进程本身之前拦截它吗?

例如,然后我就能够执行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(为了使< <(...)构造起作用)。

答案1

据我所知,没有 shell 方法可以完成您正在尝试的操作,必须通过自定义程序来完成。

使用ptrace()监视进程,类似于调试器的方式。当进程收到信号时,它将被停止,并且监视程序将收到通知(其调用wait()将返回,并且WIFSTOPPED(status)将为true)。

然后它可以运行lsof -p <pid>以列出进程的打开文件,然后调用ptrace(PTRACE_CONT, pid, NULL, 0)以重新启动进程。

相关内容