ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • gdb를 통하여 디버깅을 하자
    2011. 11. 16. comments

    linux 시스템 환경에서 C,C++ 로 개발을 하다보면 흔히 말하는 세그폴트라 불리는 segmentation fault 오류가 발생하면 난감하게 된다. 오류가 발생하는 이유는 메모리 관련이지만 일단 오류가 발생하면 저 메세지만 내놓고 프로그램이 죽기 때문이다.

    세그폴트 오류가 발생하면 해당 프로그램의 현재 상태정보를 파일로 남기게 되어 있다.(그것을 core파일이라고 불린다) 하지만 일반적으로 그 파일의 사이즈를 0으로 설정되어 있기 때문에 아무런 흔적이 남지 않는 것이다.

    그렇다면,

    core파일을 남도록 설정을 하자


    [isupt@qqi ~]$ ulimit -c
    0
    


    위 명령을 통해서 core파일 사이즈 설정을 확인할 수 있다. 결과는  0 이다. 오류를 확인하기 위하여 크기를 최대치로 설정을 해야 한다.

     
    [isupt@qqi ~]$ ulimit -c unlimited
    [isupt@qqi ~]$ ulimit -c
    unlimited
    
    


    주의사항으로 ulimit 명령으로 변경한 사항들은 해당 터미널에만 반영다. 새로 연결한 터미널에는 반영되지 않으니 디버깅을 할 때에는 명령을 내린 터미널에서 프로그램을 실행을 해야 한다.
    마지막으로 한가지 작업을 더 해주어야 한다.

    컴파일 할 때 디버깅을 옵션을 추가해야 한다.

    gdb를 사용하려면 코딩되어 있는 함수와 변수의 Symbol 테이블 정보가 필요하다. 그래야 core파일에 남겨져 있는 정보를 해당 테이블과 비교하여 어느 위치에서 문제가 발생하였는지 확인 할 수 있다. 디버깅 옵션은 컴파일 할 때   -g와 -ggdb 옵션을 둘다 포함시켜 주시면 된다.

    자, 진짜로 이제 준비가 다 되었다. 프로그램이 세그폴트로 죽기만 하면 된다.

    다음은 이해를 높이기 위해 샘플 코드를 통하여 실제 사용하는 예제다. 아래는 segfault를 고의적으로 발생시키는 코드이다.

    #include <stdio.h>
    
    int main()
    {
            char *a;
            *(a+5) = '4';
            printf( "%s", a );
            return 0;
    }
    


    -g와 -ggdb 옵션을 주고 컴파일 한 후 실행하면 segfault가 발생하고 core파일이 생성된다.  gdb를 통하여 분석을 해보자.

    [isupt@qqi ~]$ gdb -c core.30164 ./test
    



    -c 옵션은 core파일을 가리키는 옵션을 의미하며, 실행한 프로그램 파일을 뒤에 함께 입력합니다.
    시작과 동시에 문제가 된 위치가 출력된다. backtrace(축약명령어는 bt)로 함수호출을 확인하고 원인이 되는 함수 위치와 소스코드 라인까지 나오니, 이제부터 슬슬 원인을 찾아내기만 하면 된다.

    GNU gdb Red Hat Linux (6.3.0.0-1.132.EL4rh)
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
    
    Core was generated by `./test'.
    Program terminated with signal 11, Segmentation fault.
    Reading symbols from /lib/tls/libc.so.6...done.
    Loaded symbols for /lib/tls/libc.so.6
    Reading symbols from /lib/ld-linux.so.2...done.
    Loaded symbols for /lib/ld-linux.so.2
    #0  0x0804838a in main () at test.c:6
    6               *(a+5) = '4';
    
    (gdb) bt
    #0  0x0804838a in main () at test.c:6
    
     


    반응형

    댓글

Designed by Tistory.