Question

From a bash script, I'm trying to handle segmentation faults from a c++ program. I've read that using trap on SIGCHLD can be used for this purpose. Inside the trap I should be able to test for $? to get the return code from the program. See https://unix.stackexchange.com/questions/24307 for example.

It's not working for me, and I can't figure out why.

Here is the script:

#! /bin/bash

set -bm

trap 'echo "Trap result code $?"' CHLD

echo "Script: starting program"
./sigsegv
echo "Script: result code from program was $?"

As you might guess, the sigsegv program just causes a segfault:

#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;
}

When I run the wrapper script, I get this:

$./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

The key piece was Trap result code 0. That's where I expected it to say 139 to indicate a SIGSEGV (which is 128 base value + 11 for SIGSEGV).

In case it matters, RHEL 6.2, bash 4.1.2(1)-release.

Was it helpful?

Solution

I'm not positive, but I think the shell has not yet updated the value of $? at the time the handler for CHLD is called. Consider this script:

set -bm

trap 'echo "Trap result code $?"' CHLD

echo "Script: starting program"
(exit 9)
(exit 11)
echo "Script: result code from program was $?"

I replace your C++ program with a simple subshell that simulates a seg fault. When I run it, the CHLD trap prints "Trap result code 9", indicating that the trap is seeing the exit status of the command prior to the one that triggers the trap. Changing the value of the first subshell call to exit changes the value printed by the trap.


The question you link to traps the EXIT pseudo-signal. Without diving into the bash source code, I suspect that what happens is this:

  1. Set trap for CHLD

  2. For each command:

    a. Run command

    b. Execute trap for signal received

    c. Set $?

  3. Execute EXIT trap, if any

  4. Exit

In step 2b, the value of $? corresponding to the command in 2a is not yet available. In step 3, the value of $? associated with the script is available, because it's the same as the value from 2c, from the last command executed in the script.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top