Linux 下 C 異常處理技巧

2021-06-18 05:21:22 字數 3502 閱讀 3506

處理固有語言侷限性的四種技術

sachin o. agrawal (

[email protected]), 高階軟體工程師, ibm software labs, india

簡介:處理 c++ 中的異常會在語言級別上遇到少許隱含限制,但在某些情況下,您可以繞過它們。學習各種利用異常的方法,您就可以生產更可靠的應用程式。

為本文評分

保留異常**資訊

在 c++中,無論何時在處理程式內捕獲乙個異常,關於該異常**的資訊都是不為人知的。異常的具體**可以提供許多更好地處理該異常的重要資訊,或者提供一些可以附加到錯誤日誌的資訊,以便以後進行分析。

為了解決這一問題,可以在丟擲異常語句期間,在異常物件的建構函式中生成乙個堆疊跟蹤。exceptiontracer是示範這種行為的乙個類。

清單 1. 在異常物件建構函式中生成乙個堆疊跟蹤

// sample program:

// compiler: gcc 3.2.3 20030502

// linux: red hat

#include #include #include #include using namespace std;

/ class exceptiontracer

free(symbols);}};

回頁首

管理訊號

每當程序執行乙個令人討厭的動作,以致於 linux™ 核心發出乙個訊號時,該訊號都必須被處理。訊號處理程式通常會釋放一些重要資源並終止應用程式。在這種情況下,堆疊上的所有物件例項都處於未破壞狀態。另一方面,如果這些訊號被轉換成 c++ 異常,那麼您可以優雅地呼叫其建構函式,並安排多層 catch 塊,以便更好地處理這些訊號。

清單 2 中定義的signalexceptionclass,提供了表示核心可能發出訊號的 c++ 異常的抽象。signaltranslator是乙個基於signalexceptionclass的模板類,它通常用來實現到 c++ 異常的轉換。在任何瞬間,只能有乙個訊號處理程式處理乙個活動程序的乙個訊號。因此,signaltranslator採用了 singleton 設計模式。整體概念通過用於 sigsegv 的segmentationfault類和用於 sigfpe 的floatingpointexception類得到了展示。

清單 2. 將訊號轉換成異常

template class signaltranslator

static void signalhandler(int)

};public:

signaltranslator()

}; // an example for sigsegv

class segmentationfault : public exceptiontracer, public exception

};signaltranslatorg_objsegmentationfaulttranslator;

// an example for sigfpe

class floatingpointexception : public exceptiontracer, public exception

};signaltranslatorg_objfloatingpointexceptiontranslator;

回頁首

管理建構函式和析構函式中的異常

在全域性(靜態全域性)變數的構造和析構期間,每個 ansi c++ 都捕獲到異常是不可能的。因此,ansi c++ 不建議在那些其實例可能被定義為全域性例項(靜態全域性例項)的類的建構函式和析構函式中丟擲異常。換一種說法就是永遠都不要為那些其建構函式和析構函式可能丟擲異常的類定義全域性(靜態全域性)例項。不過,如果假定有乙個特定編譯器和乙個特定系統,那麼可能可以這樣做,幸運的是,對於 linux 上的 gcc,恰好是這種情況。

使用exceptionhandler類可以展示這一點,該類也採用了 singleton 設計模式。其建構函式註冊了乙個未捕獲的處理程式。因為每次只能有乙個未捕獲的處理程式處理乙個活動程序,建構函式應該只被呼叫一次,因此要採用 singleton 模式。應該在定義有問題的實際全域性(靜態全域性)變數之前定義exceptionhandler的全域性(靜態全域性)例項。

清單 3. 處理建構函式中的異常

class exceptionhandler

static void handler()

catch (segmentationfault &)

catch (floatingpointexception &)

catch (...)

//if this is a thread performing some core activity

abort();

// else if this is a thread used to service requests

// pthread_exit();}};

public:

exceptionhandler()

}; //

class a

};// before defining any global variable, we define a dummy instance

// of exceptionhandler object to make sure that

// exceptionhandler::singletonhandler::singletonhandler() is invoked

exceptionhandler g_objexceptionhandler;

a g_a;

// int main(int argc, char* argv)

回頁首

處理多執行緒程式中的異常

有時一些異常沒有**獲,這將造成程序異常中止。不過很多時候,程序包含多個執行緒,其中少數執行緒執行核心應用程式邏輯,同時,其餘執行緒為外部請求提供服務。如果服務執行緒因程式設計錯誤而沒有處理某個異常,則會造成整個應用程式崩潰。這一點可能是不受人們歡迎的,因為它會通過向應用程式傳送不合法的請求而助長拒絕服務攻擊。為了避免這一點,未捕獲處理程式可以決定是請求異常中止呼叫,還是請求執行緒退出呼叫。清單 3 中exceptionhandler::singletonhandler::handler()函式的末尾處展示了該處理程式。

回頁首

結束語我簡單地討論了少許 c++ 程式設計設計模式,以便更好地執行以下任務:

我希望您能採用這些技巧中的一些來開發無憂**。

參考資料

關於作者

sachin 六年來一直在從事 c++ 各方面的工作,包括為期三年的對各種編譯器的 c++ 物件模型的研究。目前,他在 ibm global services india 工作。您可以通過 [email protected] 與他聯絡。

Linux 下 C 程式的異常處理技巧

在 c 中,無論何時在處理程式內捕獲乙個異常,關於該異常 的資訊都是不為人知的。異常的具體 可以提供許多更好地處理該異常的重要資訊,或者提供一些可以附加到錯誤日誌的資訊,以便以後進行分析。為了解決這一問題,可以在丟擲異常語句期間,在異常物件的建構函式中生成乙個堆疊跟蹤。exceptiontracer...

C 異常處理的技巧和方法

c 中或多或少回出現一些意向不道的異常,那麼如何去捕獲這程式設計客棧個異常就非常的關鍵 這個異常可能是系統的不可控因素也有可能是程式本身才乙個異常。下面就具體的解決方案提供給大家,希望有所幫助 從最常見的分母為0的情況的例項 通過try catch final程式設計客棧ly三個關鍵字的乙個語法結構...

異常處理(下)

異常與物件 工程中的異常應用 函式級try語法 小結問題 有時在工程中只關心是否產生 了異常,而不關心具體的異常型別,c 語言可以做到嗎?c 中的 catch語句可以使用 捕獲所有的異常 include include using namespace std int test int i if i ...