Shaun Jackman wrote:
Hello,
I'm implementing a tiny vfork/exit implementation using setjmp and
longjmp. Since the function calling setjmp can't return (if you still
want to longjmp to its jmp_buf) I implemented vfork using a statement
expression macro. Here's my implementation of vfork.
jmp_buf *vfork_jmp_buf;
#define vfork() ({ \
int setjmp_ret; \
jmp_buf *prev_jmp_buf = vfork_jmp_buf, new_jmp_buf; \
vfork_jmp_buf = &new_jmp_buf; \
if( (setjmp_ret = setjmp(*vfork_jmp_buf)) != 0 ) \
vfork_jmp_buf = prev_jmp_buf; \
setjmp_ret; \
})
Unfortunately, after tracing a nasty bug I found that the same problem
applies to leaving a statement expression as does returning from a
function. The storage allocated for prev_jmp_buf and new_jmp_buf is
unallocated as soon as we leave the scope of the statement expression.
gcc quickly reuses that stack space later in the same function,
overwriting the saved jmp_buf. Does anyone have a suggestion how I can
allocate some storage space here for prev_jmp_buf and new_jmp_buf that
will last the lifetime of the function call instead of the lifetime of
the statement expression macro? My best idea was to use alloca, but it
wouldn't look pretty. Can someone confirm that memory allocated with
alloca would last the lifetime of the function call, and not the
lifetime of the statement expression?
Please cc me in your reply. Thanks,
Shaun
Alloca is like creating a stack variable, except it just gives you some
generic bytes that don't mean anything. Exiting the local scope will
trash the local variables and anything done with alloca(). You'll need
to store some information in a global variable. This C exceptions method
stores things as a linked list in nested stack frames and keeps a pointer
to the list in a global variable. Well worth studying:
http://ldeniau.home.cern.ch/ldeniau/html/exception/exception.html