8

I know the definition of setjmp and longjmp. setjmp stores the environment in stack context and the other one restores.

But i think there is somewhere some lack of understanding in my part. Can someone explain me, with the help of good examples as how can i assure, and how it will be saved and how it will be restored?

I saw the there are a lot of CPU registers pointed in jmp_buf. But how do i assure that it is restored?

Kindly help me to explain with neat examples. I googled and referred to other questions with stack overflow, but none give clear examples.

Huge huge thanks in advance.

P.S: It should be from Linux/ Unix context only.

RajSanpui
  • 11,556
  • 32
  • 79
  • 146
  • 3
    have you read through http://en.wikipedia.org/wiki/Setjmp.h ? Compile the examples and use `objdump` to see what is happening with the registers – Fredrik Pihl Jul 31 '11 at 17:08
  • Example of use: http://stackoverflow.com/questions/3291382/coming-back-to-life-after-segmentation-violation/3291847#3291847 – ninjalj Jul 31 '11 at 17:29

1 Answers1

8

When calling longjmp(), all those registers are restored automatically, and execution continues at the corresponding call to setjmp(), but this time setjmp() has a different return value (similar to how fork() has different return values in parent and child).

setjmp()/longjmp() save only a limited environment. In particular, they just save the stack pointer, not the full stack, so you can only return to the same function or to a calling function. POSIX has setcontext(), which allows to switch between stacks, making it more immediately useful for implementing things like userspace threads (fibrils, green-threads, ...).

ninjalj
  • 42,493
  • 9
  • 106
  • 148
  • Thank you for the answer, and sorry for late response. I am just checking your and Wikipedia example. – RajSanpui Jul 31 '11 at 17:46
  • What is the point in using `sigprocmask(SIG_UNBLOCK, &ss, NULL);` when you are initially not masking it? – RajSanpui Jul 31 '11 at 17:52
  • The example i got it, thanks. So on first instance setjmp returns "0" so the loop isn't entered, and instead a division by zero happens (SIGFPE) which takes it to signal handler, from where longjmp is called, and it returns non-zero value, hence entering the if statement and finally goes to exit. It is clear now, but why the sigprocmask? It is redundant, unless you have used SIG_BLOCK first. Right? – RajSanpui Jul 31 '11 at 17:57
  • 1
    @kingsmasher1: see the comment, according to POSIX a signal is blocked while executing its own signal handler (unless you pass `SA_NODEFER` to `sigaction()`). Normally, the signal is unblocked when returning from the handler, but we never return, hence the explicit unblock. It would be better to use `sigsetjmp()`/`siglongjmp()` instead, they should take care of that. – ninjalj Jul 31 '11 at 19:06
  • It would be better to use `SA_NODEFER`, at least from a performance standpoint. `sigprocmask`, `sigsetjmp`, and `siglongjmp` each incur a syscall, which is rather expensive. – R.. GitHub STOP HELPING ICE Sep 07 '11 at 21:28