What are setjmp and longjmp ?

setjmp and longjmp are C library functions intended for exception handling.

setjmp saves the current execution state into a structure of type jmp_buf. Later, a longjmp call can transfer control to the point immediately after the call to previous setjmp. The return value from setjmp indicates whether control reached that point normally or from a call to longjmp:

  1. jmp_buf state;
  2. if( setjmp(state) == 0 ) // save the current state , returns 0 first time.
  3. {
  4.         // ...
  5.         // on error
  6.         longjmp(state,-1); // this returns -1 at line 2
  7.         // ...
  8. }else{
  9.         printf("something wrong\n");
  10. }
  11.  

Implementation

The prototypes for the functions are defined in setjmp.h:

int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);
 

Let us typedef the jump_buf to hold the x86 register state. Note that the struct _jmp_buf has to be typedefd to an array to comply with the C standard.

typedef struct _jmp_buf {
        unsigned ebx,ecx,edx,esi,edi,ebp,esp,eip;
        int ret;
} jmp_buf[1];
 

Implementation of the routines in X86 assembly ( gcc AT&T syntax):

.text
.globl setjmp
.type    setjmp,@function
setjmp:

        movl  4(%esp),%eax      ;
        movl  %ebx,0(%eax)      ;
        movl  %ecx,4(%eax)      ;
        movl  %edx,8(%eax)      ;
        movl  %esi,12(%eax)     ;
        movl  %edi,16(%eax)     ;
        movl  %ebp,20(%eax)     ;
        popl  %edx              ;
        movl  %esp,24(%eax)     ;
        movl  %edx,28(%eax)     ;
        xorl  %eax,%eax         ;
        pushl %edx              ;

        ret;

.text
.globl longjmp
.type    longjmp,@function
longjmp:

; process parameters
        movl  4(%esp),%eax      ; jmp_buf
        movl  8(%esp),%ebx      ; ret val

; fix the ret val if it 0
        test %ebx,%ebx          ;
        jnz 0f                  ;
        incl %ebx               ;
0:     
        movl  %ebx,32(%eax)     ; save retval

; restore registers
        movl  0(%eax),%ebx      ;
        movl  4(%eax),%ecx      ;
        movl  8(%eax),%edx      ;
        movl  12(%eax),%esi     ;
        movl  16(%eax),%edi     ;
        movl  20(%eax),%ebp     ;
        movl  24(%eax),%esp     ;
        pushl 28(%eax)          ;
        movl  32(%eax),%eax     ;  ret val
        ret                     ;