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

c, c++

Solution

`jmp_buf` is not particularly well documented. In linux headers, you can find something like:

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];

Setting it to zero and then test whole size may be a lost of time.

Personally, I would keep a pointer to this buffer, initializing it to NULL and setting it right before setjmp.

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

It is the same idea as having a separate flag. Moreover you can allocate jmp buffers dynamically if necessary.

Problem

We have implemented "longjmp–Restore stack environment" in our code base. The `longjmp` routine is called by a particular `error_exit` function which can be invoked from anywhere. Thus it is possible that when `longjmp` is called the `setjmp` routine may not have been called and the buffer can have invalid value leading to a crash. Can I initialise the buffer to `NULL` or is there any check available to check for unset or invalid value. One way is that I can set a flag variable whenever `setjmp` is called, and I can check against that. But that is only a hack. ``` void error_exit() { extern jmp_buf buf; longjmp(buf, 1); return 1; } ``` Can I do something like this? ``` void error_exit() { extern jmp_buf buf; if(buf) longjmp(buf, 1); return 1; } ``` The code is mixed C/C++, I know I can replace `setjmp` and `longjmp` with C++ exception handling everywhere, but that is not possible now, can I instead catch `longjmp` with invalid buffer which leads to a crash?

Original source