簡體   English   中英

檢查跳轉緩沖區是否有效(非本地跳轉)

[英]Check if jump buffer is valid or not (non-local jumps)

我們在代碼庫中實現了“longjmp-Restore堆棧環境”。 longjmp例程由特定的error_exit函數調用,該函數可以從任何地方調用。

因此,當調用longjmp時,可能沒有調用setjmp例程,並且緩沖區可能具有導致崩潰的無效值。

我可以將緩沖區初始化為NULL還是可以檢查是否有未設置或無效的值。 一種方法是每當調用setjmp時我都可以設置一個標志變量,我可以檢查它。 但那只是一個黑客。

void error_exit()
{
    extern jmp_buf buf;
    longjmp(buf, 1);
    return 1;
}

我可以這樣做嗎?

void error_exit()
{
    extern jmp_buf buf;

    if(buf)
       longjmp(buf, 1);

    return 1;
}

代碼是混合的C / C ++,我知道我可以在任何地方用C ++異常處理替換setjmplongjmp ,但現在這是不可能的,我可以用無效緩沖區捕獲longjmp導致崩潰嗎?

jmp_buf沒有特別好記錄。 在linux標題中,你可以找到類似的東西:

typedef int __jmp_buf[6];

struct __jmp_buf_tag {
  __jmp_buf __jmpbuf;       /* Calling environment.  */
  int __mask_was_saved;     /* Saved the signal mask?  */
  __sigset_t __saved_mask;  /* Saved signal mask.  */
};

typedef struct __jmp_buf_tag jmp_buf[1];

將其設置為零然后測試整個大小可能會浪費時間。

就個人而言,我會保留一個指向此緩沖區的指針,將其初始化為NULL並在setjmp之前設置它。

  jmp_buf physical_buf;
  jmp_buf *buf = NULL;
  ...
  buf = &physical_buf;
  if (setjmp(*buf)) {
    ...
  }

這與擁有單獨的旗幟的想法相同。 此外,您可以根據需要動態分配jmp緩沖區。

知道緩沖區是否已設置並不是一個真正的問題,您可以只擁有一個包含該信息的輔助變量。

真正的問題是你不能longjmp橫行,這是有不確定的行為,並且由於根本原因無法工作。 從您調用setjmp的函數返回后,該函數的堆棧將被無效並被后續調用覆蓋。 所以setjmp上下文不再有效。 我不是在談論jmp_buf本身,而是談論它中記錄的堆棧狀態。

所以你唯一能做的就是有一個輔助變量來記錄你是否已經設置了緩沖區,並且一旦你將函數與setjmp放在一起就會解除設置。

好問題。

據我所知,從POSIX標准( http://pubs.opengroup.org/onlinepubs/9699919799/functions/longjmp.html http://pubs.opengroup.org/onlinepubs/9699919799/functions/setjmp.html http ://pubs.opengroup.org/onlinepubs/9699919799/basedefs/setjmp.h.html ) jmp_buf是不透明的,除了后一個引用要求它是一個數組類型:

<setjmp.h>頭文件應定義數組類型jmp_buf和... sigjmp_buf

我相信在實踐中你會保存bzero()緩沖區,並在跳轉到它之前將它與零進行比較,但理論上,在一些尚待發現的POSIX系統中,所有零jmp_buf都是允許的。 如果你(我不會)打擾這一點,一個選擇是set_jmp虛擬緩沖區你永遠不會使用一些跳躍點,然后memcmpjmp_buf反對這種假jmp_buf做前跳。 這樣你只能使用合法的(即由set_jmp初始化) jmp_buf

另一種方法是維護一個單獨的標志,指示它是否已經初始化(或者在struct包裝)。

我相信我應該在manpage re set_jmplong_jmp上插入強制警告,因為它使應用程序難以閱讀,並且對信號處理有不可預測的影響(后者用sigsetjmp() )。 此外,在C ++上下文中,它顯然不會展開您的異常處理程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM