실무활용 가능성 실험

강제종료시 호출스택 남기는 방법

무한 나무 2023. 6. 23. 21:21
#include <iostream>
#include <csignal>
#include <execinfo.h>

void signalHandler(int signum) {
    std::cout << "Received signal:"  << signum << std::endl;

    /* Get the backtrace*/
    const int MAX_FRAMES = 100;
    void* frames[MAX_FRAMES];
    int numFrames = backtrace(frames, MAX_FRAMES);
    char** symbols = backtrace_symbols(frames, numFrames);

    if (symbols != nullptr) {
        for (int i = 0; i < numFrames; ++i) {
            // symbols[i] 로 호출함수 이름 얻어서 기록하기
        }
        free(symbols);
    }

    /* Terminate the program */
    std::exit(signum);
}

int main() {
    // Register the signal handler
    std::signal(SIGSEGV, signalHandler);  // Handle segmentation fault signal
    std::signal(SIGABRT, signalHandler);
    std::signal(SIGILL, signalHandler);
    
    // Your program code

    return 0;
}

 

위 예제에서 signalHandler 함수는 시그널 핸들러로 등록됩니다. 여기서는 SIGSEGV 시그널(세그멘테이션 폴트)을 처리하는 예시로 작성되었습니다. 시그널 핸들러가 호출되면 해당 시그널 번호와 호출 스택 정보를 로그에 출력한 후, std::exit() 함수를 사용하여 프로그램을 강제 종료합니다.

backtrace() 함수와 backtrace_symbols() 함수를 사용하여 호출 스택 정보를 얻을 수 있습니다. 이를 활용하여 로그에 출력할 수 있습니다. 호출 스택 정보를 얻기 위해서는 컴파일 시 -rdynamic 옵션을 사용하여 실행 파일에 심볼 정보를 포함해야 합니다.

위 예제는 SIGSEGV 시그널에 대한 핸들러로 작성되었지만, 다른 시그널에 대해서도 동일한 방식으로 핸들러를 등록하고 호출 스택 정보를 얻을 수 있습니다. 시그널 핸들러를 등록하는 부분은 main() 함수 시작 전에 수행되어야 합니다.

 

 

SIGSEGV ("Segmentation Violation")

시스템에서 발생하는 예외적인 상황 중 하나로, 프로그램이 잘못된 메모리 접근을 시도할 때 발생합니다. 예를 들어, 잘못된 포인터를 역참조하거나, 할당되지 않은 메모리를 접근하려고 할 때 발생할 수 있습니다. SIGSEGV 시그널은 프로그램이 더 이상 안전하게 진행될 수 없는 메모리 오류를 나타내며, 기본적으로는 프로그램을 강제로 종료시킵니다.

 

SIGABRT (Abort Signal):

  • SIGABRT는 프로그램 자체가 비정상적인 상황을 감지하여 스스로를 중단하고자 할 때 발생하는 시그널입니다.
  • 주로 abort() 함수가 호출되었을 때 발생하며, 프로그램이 심각한 오류를 감지하고 중단해야 할 때 사용됩니다.
  • 일반적으로 프로그램 내부의 논리 오류나 잘못된 상태를 감지할 때 사용되며, 디버깅이나 예외 처리에 활용될 수 있습니다.

SIGILL (Illegal Instruction Signal):

  • SIGILL은 프로세스가 비정상적인 명령어나 명령어의 시퀀스를 수행하려고 할 때 발생하는 시그널입니다.
  • 주로 잘못된 기계어 명령어, 잘못된 CPU 명령어 또는 CPU 아키텍처와 관련된 문제가 발생했을 때 발생합니다.
  • 일반적으로 프로그램 내부에서 잘못된 명령어 실행을 감지하고 처리해야 할 때 사용됩니다.
  • SIGILL은 보안 관련 문제나 호환성 문제 등을 확인하는 데에도 사용될 수 있습니다.