Question

a piece of code here

jmp_buf mark;
int Sub_Func()  
{  
    int be_modify, jmpret;    
    be_modify = 0;    
    jmpret = setjmp( mark );  
    if( jmpret == 0 )  
    {  
        // sth else here 
    }  
    else  
    {  
        // error handle 
        switch (jmpret)  
        {  
            case 1:  
                printf( "Error 1\n");  
                break;  
            case 2:  
                printf( "Error 2\n");  
                break;  
            case 3:  
                printf( "Error 3\n");  
                break;  
            default :  
                printf( "Unknown Error");  
                break;  
        }  
        printf("after switch\n");        
    }     
    return jmpret;  
}  

void main( void )  
{  
    Sub_Func();   
    // the longjmp after setjmp
    longjmp(mark, 1);  
}  

the result is:
Error 1
after switch
Segmentation fault

I know the reason maybe longjmp jump back to the previous stack. but I'm not sure about the detail, and what kind of value has been stored in 'mark', can anyone explain that?

Was it helpful?

Solution

setjmp() and longjmp() work by recording a stack frame position. If you record the stack frame in Sub_Func() but return from the function before calling longjmp(), the stack frame is no more valid. longjmp() is meant to be called in the same function than setjmp() (subfunction is ok).

OTHER TIPS

You are trying to longjmp back to a deeper function. You can only longjmp back to a shallower function.

So if A calls setjmp, then calls B, then B can longjmp back into A.

But if A calls b, B calls setjmp, B returns to A, A cannot longjmp back to B.

You have invoked undefined behavior by violating the following (7.13.2.1):

The longjmp function restores the environment saved by the most recent invocation of the setjmp macro in the same invocation of the program with the corresponding jmp_buf argument. If there has been no such invocation, or if the function containing the invocation of the setjmp macro has terminated execution217) in the interim, or if the invocation of the setjmp macro was within the scope of an identifier with variably modified type and execution has left that scope in the interim, the behavior is undefined.

217) For example, by executing a return statement or because another longjmp call has caused a transfer to a setjmp invocation in a function earlier in the set of nested calls.

In short, longjmp cannot be used to jump to a setjmp point in a function which has already returned.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top