본문 바로가기
프로그래밍/C

C언어 ] setjmp(), longjmp()

by eteo 2023. 5. 7.

 

 

setjmp()와 longjmp()함수를 사용하기 위해서는 먼저 setjmp.h를 포함해야한다.

#include <setjmp.h>

 

 

 

쉽게 생각하면 setjmp()는 시스템 복원 지점을 만들고, longjmp()는 시스템 복원을 하는 것과 같다.

 

setjmp()

int setjmp(jmp_buf env);

setjmp() 함수는 현재의 위치(스택 환경)을 저장하고, 나중에 longjmp() 함수를 호출되었을 때 그 위치로 다시 돌아가는 데 사용된다.

 

 

 

longjmp()

void longjmp(jmp_buf env, int val);

longjmp() 함수는 setjmp() 함수를 통해 저장된 위치로(스택환경으로) 프로그램 실행을 이동(복원)하는 데 사용된다.

longjmp() 함수가 호출되면 setjmp() 함수 호출 이후에 발생한 모든 지역 변수 및 레지스터 상태가 소멸됨을 의미한다.

 

 

 

 

 

jmp_buf

jmp_buf라는 자료형은 setjmp() 함수가 호출된 시점의 프로그램 상태를 저장하기 위한 버퍼로, jmp_buf에 저장되는 정보는 특정 구현과 컴파일러에 따라 다를 수 있지만, 일반적으로는 CPU 레지스터 정보와 함께 스택 프레임 정보가 포함된다.

이렇게 저장된 정보는 longjmp() 함수를 호출하여 setjmp() 함수가 호출되었던 위치로 돌아갈 때, 프로그램이 다시 해당 상태로 복원될 수 있도록 해준다.

따라서 jump_buf는 프로그램 실행 중에 메모리에 상주하며 어느 위치에서든 사용 가능한 전역변수나 static 변수로 선언될 필요가 있다.

 

 

 

 

 

setjmp() 함수의 리턴값

1. 최초 호출 : 스택 환경을 저장한 후 값 0을 리턴한다.

2. longjmp() 함수로 인한 복귀 : longjmp() 호출의 결과로 리턴하는 경우, longjmp() 함수를 통해 전달된 val 인수를 리턴한다.

 

따라서 setjmp()의 리턴값이 0인지 아닌지 확인하면, 최초호출인지 또는 longjmp()로 인한 복귀인지 알 수 있다.

 

 

 

 

 

주의사항

❗ longjmp() 함수 호출시 val 인수는 0이 아닌 값이어야 한다. 만약 val로 0을 전달하면 자동으로 이 값이 1로 대체된다. 최초호출을 구분하기 위해서이다.

 

longjmp() 함수를 호출하기 전에 setjmp() 함수를 호출하는 함수가 리턴하지 않는지 확인해야 한다. setjmp() 함수를 호출하는 함수가 리턴된 후 longjmp()을 호출하면 예측 불가능한 작동이 발생할 수 있다.

-  만약 foo()에서 setjmp()를 호출했으면 foo()가 리턴한 후에 해당 env로(스택환경으로) longjmp()를 호출하면 오류가 발생한다는 뜻이다. main()에서 setjmp()를 호출하면 그런 걱정은 없겠다.

 

 

 

 

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

jmp_buf env;

int main(void)
{

    int ret;
    char ch;

    if ((ret = setjmp(env)) == 0) printf("line: %d, ret = %d\n", __LINE__, ret);
    else printf("line: %d, ret = %d\n", __LINE__, ret);

    while (1)
    {
        printf("Enter 'y' to jump to the beginning\n");
        ch = getchar();
        getchar();
        if (ch == 'y')
        {
            longjmp(env, ++ret);
        }
    }

    return 0;
}

 

 

 

 

 

참고자료 : https://www.ibm.com/docs/ko/i/7.3?topic=functions-longjmp-restore-stack-environment