too much abstraction



All timestamps are based on your local time of:

Posted by: stak
Posted on: 2006-12-24 12:16:57

Usually you can solve just about any problem by adding more layers of abstraction. Here's my recently-discovered exception to that rule:

#include <stdio.h>
#include <setjmp.h>

#define DOESNT_WORK

int setjmpWrapper( void *jmpbuf ) {
    return setjmp( *(jmp_buf *)jmpbuf );
}

void longjmpWrapper( void *jmpbuf, int retVal ) {
    longjmp( *(jmp_buf *)jmpbuf, retVal );
}

int main( int argc, char ** argv ) {
    jmp_buf jmpBuffer;
#ifdef DOESNT_WORK
    if (setjmpWrapper( &jmpBuffer )) {
        printf( "Success!\n" );
        return 0;
    }
    longjmpWrapper( &jmpBuffer, 1 );
#else
    if (setjmp( jmpBuffer )) {
        printf( "Success!\n" );
        return 0;
    }
    longjmp( jmpBuffer, 1 );
#endif
    return 1;
}


Wrappers on setjmp/longjmp code don't really work. If you think about it, it makes sense - setjmp copies the current registers into the jump buffer, so that you can roll back the machine state when you longjmp. However, the problem here is that if you use the wrapper, the stack gets unwound and rewound after the call to setjmp (i.e. when you return from the wrapper, a stack frame is thrown out). This means when you call the longjmp wrapper, the stack has changed, and restoring the stack pointer to what it used to be causes Bad Things (TM) to happen, like returning into random memory. Fortunately, it's not too hard to debug, since starting to execute random memory locations almost always throws some hardware exception, and tracing the last valid instruction gets you to the longjmp code pretty fast.

[ Add a new comment ]

 
 
(c) Kartikaya Gupta, 2004-2019. User comments owned by their respective posters. All rights reserved.
You are accessing this website via IPv4. Consider upgrading to IPv6!