Wie kann ich ein Programm abfangen, das 139 (Segmentierungsfehler) in bash zurückgibt?

10

Ich habe ein Bash-Skript, das einige Programme testet, und eines der Programme kehrt zurück, Segmentation faultalso habe ich versucht, eine Falle in den Kopf meines Skripts einzufügen:

trap "echo 'segfault occured!'" SIGSEGV

Das hat aber nichts gebracht. ich benutzte

echo $?

kurz nach dem Programm, das den Segfault erzeugt und ich bekomme 139 als Ausgabe. Wie kann ich eine Falle für diesen bestimmten Fehlercode hinzufügen?

Pithikos
quelle

Antworten:

7

trap "$instructions" SIGSEGV Fängt Segmentierungsfehler in der Shell selbst ab.

Wenn Sie Ihr Skript unter ausführen set -e, können Sie eine Falle auf EXIT(oder 0) setzen. Es wird ausgeführt, wenn Ihr Skript beendet wird (sei es aufgrund eines Befehls, der einen Status ungleich Null zurückgibt, oder indem Sie explizit aufrufen exitoder das Ende des Skripts fallen lassen). Um auf einen Segmentierungsfehler zu testen, überprüfen Sie den $?Eintritt in die Falle. (Beachten Sie, dass $?dies 139 sein kann, da das Programm normal mit dem Status 139 zurückgegeben wird. Dies ist vermeidbar, wenn Sie Ihre Verarbeitung in der Shell durchführen.)

set -e
trap 'case $? in
        139) echo "segfault occurred";;
      esac' EXIT

In bash oder ksh oder zsh müssen Sie nicht set -enach jedem Befehl, der einen Status ungleich Null zurückgibt, einen Trap ausführen ERR. Stattdessen können Sie einen Trap aktivieren. Nach wie vor müssen Sie den $?Zugang zum Trap überprüfen , und 139 kann (aber selten) bedeuten, dass das Programm diesen Status zurückgegeben hat.

Gilles 'SO - hör auf böse zu sein'
quelle
6

Von man bash:

   trap [-lp] [[arg] sigspec ...]
          The command arg is to  be  read  and  executed  when  the  shell
          receives  signal(s)  sigspec.

Wenn Ihr Programm fehlerhaft ist, erhält Ihre Bash nur eine, SIGCHLDweil ein Kind beendet wurde (auf welche Weise auch immer).

Sie können jedoch den Exitcode verwenden $?, der in einer bestimmten Bedingung gespeichert ist, und Trap SIGCHLD:

trap 'if [[ $? -eq 139 ]]; then echo "segfault !"; fi' CHLD

Beachten Sie, dass dies set -bmmöglicherweise erforderlich ist, wenn dies (was wahrscheinlich der Fall ist) in einer nicht interaktiven Bash (z. B. einem Skript) verwendet wird.

Bearbeiten: Siehe auch diese (Gilles ') Antwort zu einem ähnlichen Problem mit bashund trap.

sr_
quelle
Es passiert etwas Seltsames. Ich benutze eine Falle trap "echo 'something happened!'" {1..64}und bekomme trotzdem nichts. Ich habe es sogar mit set -bmund set -o monitoraber nada versucht .
Pithikos
Haben Sie dies interaktiv versucht? trap "echo 'something happened'" {1..31}funktioniert für mich (ohne die !und die Signalspezifikationen, die dazu führen bash: trap: XX: invalid signal specification).
sr_