#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf g_my_jump_buffer;
bool try_signal (int sig)
{
int result;
result = setjmp(my_jump_buffer, sig);
printf ("setjmp(): resutl %d \r\n", result);
if (sig==result)
return true;
return false;
}
void signal_handler (int sig)
{
printf ("signal_handler(%d) \r\n", sig);
longjmp (g_my_jump_buffer, sig);
}
int main (void)
{
unsigned int* p = (unsigned int*)0xffffffff;
signal (SIGBUS, signal_handler);
while (1)
{
if (try_signal (SIGBUS)==0)
{
printf ("no signal \r\n");
*p = 0x00000001;
}
else
{
printf ("signal \r\n");
}
}
return 0;
}
이런식으로 setjmp를 사용하면 프로그램이 망한다.
setjmp시 현재 스택 포인터를 저장하는 역할을 하기 때문에 위에 처럼 setjmp를 랩핑해서 함수를 호출하여 사용하면
1. 위에 main함수에서 try_signal()을 호출하고
2. signal이 발생되어서 signal_handler()를 거쳐서
3. 다시 setjmp()함수 위치로 복귀하려 했을때
이전 try_signal()이 호출 되어서 저장했던 스택포인터는
이전 try_singal()가 main()함수로 복귀를 했으므로 저장했던 해당 스택포인터가 유효 하지 않다.
랩핑해서 사용하고 싶을땐 아래와 같이 inline함수로 구현하던가 매크로로 구현해야한다.
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf g_my_jump_buffer;
inline bool try_signal (int sig)
{
int result;
result = setjmp(my_jump_buffer, sig);
printf ("setjmp(): resutl %d \r\n", result);
if (sig==result)
return true;
return false;
}
void signal_handler (int sig)
{
printf ("signal_handler(%d) \r\n", sig);
longjmp (g_my_jump_buffer, sig);
}
int main (void)
{
unsigned int* p = (unsigned int*)0xffffffff;
signal (SIGBUS, signal_handler);
while (1)
{
if (try_signal (SIGBUS)==0)
{
printf ("no signal \r\n");
*p = 0x00000001;
}
else
{
printf ("signal \r\n");
}
}
return 0;
}