2016년 5월 13일 금요일

backtrace

사용 : 어떤 함수를 호출하는 녀석들이 너무 다양할 때, 문제 상황에서 정확히 어떤 녀석이 불린 것인지 알고자 할 때 사용.

gdb로 일일이 callstack을 출력할 수 있지만 귀찮을 때는 backtrace 사용하면 편리함.
http://man7.org/linux/man-pages/man3/backtrace.3.html

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

       #define BT_BUF_SIZE 100

       void
       dump(void)
       {
           int j, nptrs;
           void *buffer[BT_BUF_SIZE];
           char **strings;

           nptrs = backtrace(buffer, BT_BUF_SIZE);
           printf("backtrace() returned %d addresses\n", nptrs);

           /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
              would produce similar output to the following: */

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

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

           free(strings);
       }


그리고 출력하고자 하는 함수에서 조건을 걸어 주면 좀더 결과가 간략하게 출력 될 수 있음.

if (url().string().find(".jpg") != std::string::npos)
   dump();


많은 심볼을 한꺼번에 addr2line할 때는 아래와 같이 awk를 이용 가능.




awk 'match($0, /+0x[0-9a-f]*/) {
    addr = substr($0, RSTART, RLENGTH);
    print $addr
    system("addr2line -e lib/libcbe.so -apf "addr);
}
' log.txt


댓글 없음:

댓글 쓰기