Setjmp/longjmp

Ahn9807 (토론 | 기여)님의 2023년 2월 21일 (화) 01:36 판 (새 문서: 분류:POSIX 시스템 콜 == 개요 == setjmp()와 longjmp()는 C언어의 goto문과 유사하지만 다소 차이가 있다. goto문 같은 경우는 실행중의 EIP(또는 Program Count)만 변경되지만, setjmp()/longjmp()는 프로그램의 스택도 변경시킨다. Goto문 같은 경우는 local jump를 지원하지만, setjmp는 nonlocal 점프도 할 수 있다. 즉 Goto문은 같은 함수내에서만 점프할 수 있지만, setjmp는 저장된 jmp_buf로 향...)
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)


개요

setjmp()와 longjmp()는 C언어의 goto문과 유사하지만 다소 차이가 있다. goto문 같은 경우는 실행중의 EIP(또는 Program Count)만 변경되지만, setjmp()/longjmp()는 프로그램의 스택도 변경시킨다. Goto문 같은 경우는 local jump를 지원하지만, setjmp는 nonlocal 점프도 할 수 있다. 즉 Goto문은 같은 함수내에서만 점프할 수 있지만, setjmp는 저장된 jmp_buf로 향하여 점프하기 때문에, 같은 함수내에서 있을 필요가 없다. 중요한 사실은 점프문은 매우 위험하고 피해야할 프로그래밍 스킬이라는 것이다.

#include <setjmp.h> 헤더를 통해서 include한다.
int setjmp(jmp_buf env) 직접 호출하면 0을 리턴하고 longjmp를 통해서 리턴하면 0이 아닌 값을 리턴하게 된다.
void longjmp(jmp_buf env, int val)을 통해서 longjmp 구문에 들어가게 된다. val은 setjmp 호출에 대해 반환되는 값이다.

주의해야 하는 것은 setjmp를 한 함수가 return되었을 경우 longjmp를 수행하면 현재 stack frame그대로 setjmp를 함수의 stackframe처럼 반영하여 함수를 실행하게 되기 때문에, 예측 할 수 없는 결과를 가져올 수 있다는 것이다. 따라서 setjmp와 longjmp는 주의깊게 사용되어져야 한다. 즉 setjmp를 한 함수가 return되면 그 setjmp를 한 함수로 longjmp를 수행해서는 안됀다.

예제

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <signal.h>
void p1();
void intHandler();
jmp_buf env;

int main()
{
        signal( SIGINT, intHandler );
        if( setjmp( env ) != 0 ){
                printf( "오류로 인해 복귀\n" );
                exit( 0 );
        }
        else
                printf( "처음 통과\n" );

        p1();
}

void p1()
{
        while( 1 ){
                printf( "루프\n" );
                sleep( 1 );
        }
}

void intHandler()
{
        printf( "인터럽트\n" );
        longjmp( env, 1 );
}

참고

  1. https://blackcon.tistory.com/142