Superkkt Blog

Backtrace function in C/C++

2011/01/21 09:34

GNU 확장 기능인 backtrace, backtrace_symbols 함수를 사용하면 프로그램이 비정상 종료되는 상황에서 call stack을 로그로 남길 수 있다.  아래는 예제 코드이고 반드시 -rdynamic 옵션이 링크시에 주어져야만 콜스택에서 심볼명이 보이게 된다.

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>

#define BACKTRACE_BUFFER_SIZE 256

void func_2(void)
{
    int i, nptrs;
    void *buffer[BACKTRACE_BUFFER_SIZE];
    char **strings = NULL;

    nptrs = backtrace(buffer, BACKTRACE_BUFFER_SIZE);
    strings = backtrace_symbols(buffer, nptrs);
    if (!strings) {
        perror("backtrace_symbols");
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < nptrs; i++) {
        printf("%s\n", strings[i]);
    }

    free(strings);
}

void func_1(void)
{
    func_2();
}

int main(void)
{
    func_1();
    return 0;
}

아래는 예제 코드를 컴파일하고 실행한 결과이다. 참고로 -O2 등의 최적화가 들어가면 콜스택이 변할 수 있다. 불필요한 함수 호출을 컴파일러가 제거하기 때문이다.

superkkt@~/tmp$ gcc -Wall -g -rdynamic -o backtrace backtrace.c
superkkt@~/tmp$ ./backtrace
./backtrace(func_2+0x27) [0x4008db]
./backtrace(func_1+0x9) [0x400955]
./backtrace(main+0x9) [0x400960]
/lib/libc.so.6(__libc_start_main+0xfe) [0x7f7fcbaacd8e]
./backtrace() [0x4007f9]

Segmentation Fault 상황에서 시그널 핸들러를 사용해서 로그를 남기는 방법은 참조된 사이트를 참고한다.

<References>

Stack Backtracing Inside Your Program
2011/01/21 09:34 2011/01/21 09:34

trackbacks

trackbacks rss

http://superkkt.com/trackback/612

Leave a Comment