4

从 bash 脚本,我正在尝试处理来自 c++ 程序的分段错误。我读过 using traponSIGCHLD可用于此目的。在陷阱内部,我应该能够测试$?以从程序中获取返回码。例如,请参阅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 的地方(即 128 基值 + SIGSEGV 的 11)。

如果它很重要,RHEL 6.2, bash 4.1.2(1)-release。

4

1 回答 1

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 $?"

我用一个模拟段错误的简单子shell替换了你的C++程序。当我运行它时,CHLD陷阱会打印“陷阱结果代码 9”,表明陷阱在触发陷阱之前看到命令的退出状态。更改第一个 subshel​​l 调用的值以exit更改陷阱打印的值。


您链接到的问题会捕获EXIT伪信号。在不深入研究bash源代码的情况下,我怀疑会发生什么:

  1. 设置陷阱CHLD

  2. 对于每个命令:

    一个。运行命令

    湾。对收到的信号执行陷阱

    C。放$?

  3. 执行EXIT陷阱(如果有)

  4. 出口

在步骤2b中,$?2a中的命令对应的值尚不可用。在第 3 步中,$?与脚本关联的可用,因为它与脚本中执行的最后一个命令的 2c 中的值相同。

于 2013-07-29T21:40:45.350 回答