2013-07-29 116 views
4

從一個bash腳本,我試圖處理來自C++程序的分段錯誤。我讀過SIGCHLD上的trap可用於此目的。在陷阱內部,我應該可以測試$?以從程序中獲取返回代碼。例如,請參見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) - 發佈。

回答

4

我並不積極,但我認爲在調用CHLD的處理程序時,shell尚未更新$?的值。考慮一下這個腳本:

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」,指示陷阱在觸發陷阱之前看到該命令的退出狀態。將第一個子shell調用的值更改爲exit會更改陷阱打印的值。


您鏈接到陷阱EXIT僞信號的問題。如果不潛入bash源代碼,我懷疑會發生什麼情況是這樣的:

  1. CHLD

  2. 對於每個命令設置陷阱:

    一個。運行命令

    b。對收到的信號執行陷阱

    c。設置$?

  3. 執行EXIT陷阱,如果任何

  4. 退出

在步驟2b中,的$? 2a中對應於該命令的值尚不可用。在步驟3中,與腳本相關聯的$?的值爲可用,因爲它與來自腳本中執行的最後一個命令的2c的值相同。

+1

似乎是絕對正確的。我用自己的方式測試了它,用一個值得信賴的C++程序給出了一個可選的退出代碼,而不是你神祕的bash命令。在陷阱裏面,$?有上一個命令的退出碼,而不是觸發陷阱的那個。傷心,沒用。對於我特別的問題,我用$ PIPESTATUS解決了這個問題,這要歸功於這個答案:http://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another/73180# 73180 – RaveTheTadpole