How two independent jmp_bufs work?

81 views Asked by At

Hi I want to ask about setjmp/longjmp. I tried to search, but I was unsucessuful...

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

jmp_buf a, b;

void jump() {
    int aa = setjmp(a);

    if (aa)
    {
        printf("Jump!\n");
    }
    else
    {
        longjmp(b, 1); 
        printf("Should not happened...\n");
    }

    printf("End of function!\n");
}


int main(int argc, char** argv) {
    int bb = setjmp(b);

    if (bb)
    {
        longjmp(a, 1);
        printf("Should not happened...\n");
    }
    else
    {
        jump();
        printf("What here?\n");
    }

    printf("Exit\n");
    return 0;
}

The question is, what will happen after last printf in jump()... I tried this code and it turned into infinite loop. Why? I though that setjmp will store environment data, so the jump function shall return after it's original call... I'm quiet confused. Thanks for reply :)

1

There are 1 answers

1
Gene On BEST ANSWER

The whole program has undefined behavior.

  1. setjmp(b); stores the stack state.
  2. jump() is called.
  3. `setjmp(a);' stores the stack state again.
  4. longjmp(b, 1); restores the stack to the point before jump() was ever called. So the state stored in a is now invalid.
  5. Execution continues at the if in main().
  6. longjmp(a, 1); is called. Ouch. This causes undefined behavior due to 4 above.

Your confusion probably results from the slightly imprecise use of the world "return" in the Linux docs for setjmp().

The stack context will be invalidated if the function which called setjmp() returns.

In your example, the function jump() didn't return in the normal way, but the effect was the same: the stack was "chopped" by the first longjmp() to the state before jump(), which is what a return does, too.