我有一个围绕大型可执行文件的shell包装器.它做了这样的事情:
run/the/real/executable "$@" &
PID=$!
# perform
# a few
# minor things
wait $PID
# perform some
# post-processing
在等待之后它执行的操作之一是检查核心转储并处理崩溃,然而,到那时,该过程已经死亡并且一些信息不再可用.
在将脚本传递给孩子本身之前,shell脚本是否可以拦截致命信号(SIGSEGV或SIGBUS)?
然后我就可以执行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 < &1)
echo $outputfiles
wait $NPID
上述测试需要使用ksh或bash(对于<
最佳答案
据我所知,没有shell方法可以做你正在尝试的东西,它必须从自定义程序完成.
使用ptrace()来监视进程,类似于调试器的工作方式.当进程收到一个信号时,它将被停止,监控程序将被通知(它的wait()调用将返回,WIFSTOPPED(status)将为真).
然后它可以运行lsof -p< pid>列出进程的打开文件,然后调用ptrace(PTRACE_CONT,pid,NULL,0)重新启动进程.