Why a segmentation fault occurs calling a function inside setjmp()?

Multi tool use
Multi tool use
The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Why a segmentation fault occurs calling a function inside setjmp()?



I do not understand why in the function middleFunc(), a segmentation fault is raisen when entry_point(arg) is invoked inside the if ( setjmp(middle) ) statement.


middleFunc()


entry_point(arg)


if ( setjmp(middle) )


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


jmp_buf start,middle,end;


void finalFunc(void *v)
{
printf("hellon");
return ;
}


void middleFunc(void (*entry_point)(void *), void *arg)
{
//just debug : this does not cause segmentation fault
entry_point(arg);

if ( setjmp(middle) ){
//this casues the segmentation fault
entry_point(arg);
//once the entry point (finalFunc) is executed go to jmp_buffer end
longjmp(end,1);
}
else {
longjmp(start,1);
}
}

int main(){

if (setjmp(end)){
//exit since finalFunc has been executed
return 0;
}

if (setjmp(start)){
//the middleFunc has previously set the jmp_buffer middle
longjmp(middle,1);
}

else{
int x = 1;
middleFunc(finalFunc,(void*)&x);
}

}




1 Answer
1



In your code the behavior is undefined. You are not allowed to long-jump to middle after middleFunc finished execution (either by normal completion or by another longjmp).


middle


middleFunc


longjmp



7.13.2.1 The longjmp function



2 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 execution248) in the interim [...] the behavior is undefined.


longjmp


setjmp


jmp_buf


setjmp



248) 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.


return


longjmp


setjmp



In your code middleFunc sets up middle and after that immediately exits to main by doing longjmp(start,1). After that jump middle is no longer valid. You are no longer allowed to jump to middle from anywhere. setjmp/longjmp mechanism only supports jumps up the call stack. You cannot do side-jumps or down-jumps. Only up-jumps are supported.


middleFunc


middle


main


longjmp(start,1)


middle


middle


setjmp/longjmp



From the practical point of view, you are attempting to jump into a "dead" function invocation and somehow expecting that function parameter values are still valid (like, preserved from the previous invocation or something). But they are not. setjmp/longjmp do not preserve/restore parameter values. Value of entry_point in that "dead" invocation is probably some garbage. When you attempt to make a call through entry_point, the code coredumps.


setjmp/longjmp


entry_point


entry_point



P.S. It is true that side-jumping with setjmp/longjmp is sometimes used to implement co-routines. However, such usage falls outside the boundaries of standard library specification. And in any case such usage will never expect preservation of parameter values.


setjmp/longjmp





thank you, is this the reason for which co-rotuine are implemented with a new allocated stack ?
– Neo
2 mins ago








By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

8hveZ6yegpz w,w2nCc0D9nF8o5 rF Scmqadr273f19vcUw0HGcPWzC 9uXH RV
AiKBBIcgb NtVE9nvC Jh99fAi q0DtI8PDBCtz,y7 ZZxnBJ,1fWIhheD,n,oMs

Popular posts from this blog

Makefile test if variable is not empty

Visual Studio Code: How to configure includePath for better IntelliSense results

Will Oldham