从bash脚本,我正在尝试处理来自c ++程序的分段错误。我已经读过在trap
上使用SIGCHLD
可以用于此目的。在陷阱内部,我应该能够测试$?
以从程序中获取返回码。例如,请参阅https://unix.stackexchange.com/questions/24307。
这对我不起作用,我无法弄明白为什么。
这是脚本:
#! /bin/bash
set -bm
trap 'echo "Trap result code $?"' CHLD
echo "Script: starting program"
./sigsegv
echo "Script: result code from program was $?"
正如您可能猜到的那样,sigsegv
程序只会导致段错误:
#include <csignal>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
cout << "C++ will now cause a SIGSEGV" << endl;
raise(SIGSEGV);
cout << "After signal -- shouldn't get here" << endl;
return 0;
}
当我运行包装器脚本时,我得到了这个:
$./wrappersimple.sh
Script: starting program
C++ will now cause a SIGSEGV
Trap result code 0
./wrapper.sh: line 8: 26368 Segmentation fault (core dumped) ./sigsegv
Script: result code from program was 139
关键部分是Trap result code 0
。这就是我期望它说139表示SIGSEGV(SIGSEGV为128基础值+11)。
如果重要,RHEL 6.2,bash 4.1.2(1)-release。
答案 0 :(得分:4)
我不是肯定的,但我认为在调用$?
的处理程序时,shell尚未更新CHLD
的值。考虑一下这个脚本:
set -bm
trap 'echo "Trap result code $?"' CHLD
echo "Script: starting program"
(exit 9)
(exit 11)
echo "Script: result code from program was $?"
我用一个模拟seg错误的简单子shell替换你的C ++程序。当我运行它时,CHLD
陷阱打印“陷阱结果代码9”,表示陷阱在触发陷阱之前看到命令的退出状态。将第一个子shell调用的值更改为exit
会更改陷阱打印的值。
您链接的问题会捕获EXIT
伪信号。如果不深入研究bash
源代码,我怀疑会发生什么:
设置CHLD
对于每个命令:
一个。运行命令
湾执行收到信号的陷阱
℃。设置$?
执行EXIT
陷阱,如果有的话
退出
在步骤2b中,对应于2a中的命令的$?
的值尚不可用。在步骤3中,与脚本关联的$?
的值可用,因为它与脚本中执行的最后一个命令的2c值相同。