C語言中的setjmp和longjmp函式

2021-06-17 16:41:57 字數 2124 閱讀 5133

c語言的setjmp:異常處理與構建協作式多工系統

int setjmp(jmp_buf envbuf)

巨集函式setjmp()在緩衝區envbuf中儲存系統堆疊裡的內容,供longjmp()以後使用,setjmp()必須使用標頭檔案setjmp.h。

呼叫setjmp()巨集時,返回值為0,然而longjmp()把乙個變原傳遞給setjmp(),該值(恆不為0)就是呼叫longjmp()後出現的setjmp()的值。

setjmp 函式用於儲存程式的執行時的堆疊環境,接下來的其它地方,你可以通過呼叫longjmp函式來恢復先前被儲存的程式堆疊環境。當setjmp和 longjmp組合一起使用時,它們能提供一種在程式中實現「非本地區域性跳轉」("non-local goto")的機制。並且這種機制常常被用於來實現,把程式的控制流傳遞到錯誤處理模組之中;或者程式中不採用正常的返回(return)語句,或函式的正常呼叫等方法,而使程式能被恢復到先前的乙個呼叫例程(也即函式)中。

對setjmp函式的呼叫時,會儲存程式當前的堆疊環境到env引數中;接下來呼叫longjmp時,會根據這個曾經儲存的變數來恢復先前的環境,並且當前的程式控制流,會因此而返回到先前呼叫setjmp時的程式執行點。此時,在接下來的控制流的例程中,所能訪問的所有的變數(除暫存器型別的變數以外),包含了longjmp函式呼叫時,所擁有的變數。

如何實現異常處理

首先設定乙個跳轉點(setjmp() 函式可以實現這一功能),然後在其後的**中任意地方呼叫 longjmp() 跳轉回這個跳轉點上,以此來實現當發生異常時,轉到處理異常的程式上,在其後的介紹中將介紹如何實現。 setjmp() 為跳轉返回儲存現場並為異常提供處理程式,longjmp() 則進行跳轉(丟擲異常),setjmp() 與 longjmp() 可以在函式間進行跳轉,這就像乙個全域性的 goto 語句,可以跨函式跳轉。

jmp_buf 異常結構

使用 setjmp() 及 longjmp() 函式前,需要先認識一下 jmp_buf 異常結構。jmp_buf 將使用在 setjmp() 函式中,用於儲存當前程式現場(儲存當前需要用到的暫存器的值),jmp_buf 結構在 setjmp.h 檔案內宣告:

typedef struct

&leftsign;

unsigned j_sp;  // 堆疊指標暫存器

unsigned j_ss;  // 堆疊段

unsigned j_flag;  // 標誌暫存器

unsigned j_cs;  // **段

unsigned j_ip;  // 指令指標暫存器

unsigned j_bp; // 基址指標

unsigned j_di;  // 目的指標

unsigned j_es; // 附加段

unsigned j_si;  // 源變址

unsigned j_ds; // 資料段

&rightsign; jmp_buf;

jmp_buf 結構存放了程式當前暫存器的值,以確保使用 longjmp() 後可以跳回到該執行點上繼續執行。

setjmp() 與 longjmp() 函式都使用了 jmp_buf 結構作為形參,它們的呼叫關係是這樣的:

首先呼叫 setjmp() 函式來初始化 jmp_buf 結構變數 jmpb,將當前cpu中的大部分影響到程式執行的積存器存入 jmpb,為 longjmp() 函式提供跳轉,setjmp() 函式是乙個有趣的函式,它能返回兩次,它應該是所有庫函式中唯一乙個能返回兩次的函式,第一次是初始化時,返回零,第二次遇到 longjmp() 函式呼叫後,longjmp() 函式使 setjmp() 函式發生第二次返回,返回值由 longjmp() 的第二個引數給出(整型,這時不應該再返回零)。

在使用 setjmp() 初始化 jmpb 後,可以其後的程式中任意地方使用 longjmp() 函式跳轉會 setjmp() 函式的位置,longjmp() 的第乙個引數便是 setjmp() 初始化的 jmpb,若想跳轉回剛才設定的 setjmp() 處,則 longjmp() 函式的第乙個引數是 setjmp() 所初始化的 jmpb 這個異常,這也說明一件事,即 jmpb 這個異常,一般需要定義為全域性變數,否則,若是區域性變數,當跨函式呼叫時就幾乎無法使用(除非每次遇到函式呼叫都將 jmpb 以引數傳遞,然而明顯地,是不值得這樣做的);longjmp() 函式的第二個引數是傳給 setjmp() 的第二次返回值

C語言中的setjmp和longjmp

在c語言中,goto語句只能在乙個函式內實現跳轉,而不能在函式間進行跳轉。如果希望在函式間跳轉,可以使用 setjmp 和 longjmp 函式。linux 會把程序的上下文儲存在 task struct 結構體中,切換時直接恢復。而 setjmp 和 longjmp 的原理也差不多 第一次呼叫se...

c語言中的setjmp和longjmp簡介

setjmp將當前程式的執行環境儲存在乙個jump buf型別的全域性變數中 因為後續要被longjmp呼叫 第一次呼叫setjmp的返回值是null 中後續的 中執行到longjmp以後,longjmp需要兩個引數,乙個是之前setjmp儲存到執行環境的全域性變數可以調整到setjmp函式 另乙個...

c語言中setjmp與longjmp(2)

如何實現異常處理 首先設定乙個跳轉點 setjmp 函式可以實現這一功能 然後在其後的 中任意地方呼叫 longjmp 跳轉回這個跳轉點上,以此來實現當發生異常時,轉到處理異常的程式上,在其後的介紹中將介紹如何實現。setjmp 為跳轉返回儲存現場並為異常提供處理程式,longjmp 則進行跳轉 丟...