2009년 3월 10일 화요일

11Day Study

11Day Study
[[[[[디버깅(Debuging)]]]]]

gcc 오류를 추적하면서 컴파일 하기
gcc -Wall -pedantic -ansi

인스트루먼트 예:
#ifdef BEBUG
printf("variable x has value = %d\n", x);
#endif

인스트루먼트 복합 적용 예:
#ifndef DEBUG
#define DEBUG 0
#endif

#define BASIC_DEBUG 1
#define EXTRA_DEBUG 2
#define SUPER_DEBUG 4

#if (DEBUG & EXTRA_DEBUG)
printf...
#endif

컴파일 방법
gcc -o cinfo --DEBUG cinfo.c

그냥 print를 활용하기
if(debug) {
sprintf(msg,...);
write_debug(msg)
}

gdb를 이용한 디버깅
gcc -g -o debugex debugex.c < = 꼭 -g 옵션이 필요함
gdb debugex
GNU gdb Red Hat Linux (6.5-37.el5_2.2rh)
Copyright (C) 2006 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/libthread_db.so.1".

(gdb) run => debugex를 실행
Starting program: /root/cstudy/maxusermem

Program received signal SIGSEGV, Segmentation fault.
0x080483ef in main () at ./maxusermem.c:14
14 *scan_ptr='\0'; => 14번째 줄 에러
(gdb) bt < = 스택을 추적하여 코드 에러 부분을 호출한 부분을 찾을 수 있음
#0 0x080483ef in main () at ./maxusermem.c:14
(gdb) backtrace => 스택을 추적하여 코드 에러 부분을 호출한 부분을 찾을 수 있음
#0 0x080483ef in main () at ./maxusermem.c:14
(gdb) print scan_ptr => scan_ptr 변수값 보기
$2 = 0x9a6f000 < Address 0x9a6f000 out of bounds>
(gdb) print ex[$-1] => ex배열의 마지막 결과값 바로 전꺼 보기
(gdb) print ex[3].key => ex배열 3번째의 key 값 보기
(gdb) print ex[0]@ => ex배열 전체 보기
(gdb) list => 소스 보기
9
10 some_memory=(char *)malloc(ONE_K);
11 if(some_memory == NULL) exit(EXIT_FAILURE);
12 scan_ptr=some_memory;
13 while(1) {
14 *scan_ptr='\0';
15 scan_ptr++;
16 }
17 exit(EXIT_SUCCESS);
18 }
(gdb) help breakpoint => 브레이크 포인트 설명 보기
(gdb) break 11 => 11번째 줄에 중단점 만들기
Breakpoint 1 at 0x80483d4: file ./maxusermem.c, line 11.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /root/cstudy/maxusermem

Breakpoint 1, main () at ./maxusermem.c:11
11 if(some_memory == NULL) exit(EXIT_FAILURE);
(gdb) print some_memory
$8 = 0x8de0008 ""
(gdb) cont => 중단점을 지나서 계속 진행
Continuing.
(gdb) next => 중단점을 지나서 다음으로 진행
(gdb) display ex[0]@ => 실행될때 마다 보여줌
(gdb) commands => 브레이크 포인트 만날 때를 제어함
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>cont => 중단점 무시하여 진행
>end => commands 나가기
(gdb) info display => 디스플레이 정보 보기
Auto-display expressions now in effect:
Num Enb Expression
1: y some_memory
(gdb) info break => 브레이크 포인트 정보 보기
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483d4 in main at ./maxusermem.c:11
breakpoint already hit 1 time
cont
(gdb) disable break 1 => 브레이크 포인트 1 비활성
(gdb) disable display 1 => 디스플레이 1 비활성
(gdb) commands 1 => 브레이크 포인트 1번을 제어
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>set variable ex = 2; => ex 변수를 2로 변경하여 처리함
>cont
>end
(gdb) run
(gdb) quit
The program is running. Exit anyway? (y or n) y
[root@waf cstudy]#

최적화 컴파일
gcc -O -g -o test ./test.c

$ splint -strict maxusermem.c => 컴파일 전에 프로그램 에러 잡기

코어 덤프 파일 만들기
gcc -g -o test ./test.c

옵션 후
#include < sys/resource.h>

static void
set_limit(void)
{
struct rlimit rlp;

rlp.rlim_cur = RLIM_INFINITY;
rlp.rlim_max = RLIM_INFINITY;

/* Core file size를 시스템 최대치로 설정 */
if (setrlimit(RLIMIT_CORE, &rlp))
Log(ERROR, "Failed to set rlimit core file size: %s",
strerror(errno));
}

위가 안 되면
ulimit -c unlimited >/dev/null 2>&1
http://my.oops.org/77 참조

[root@waf cstudy]# gdb debugex --core=./core.9794 ==> 코어 파일을 이용하여 디버그
GNU gdb Red Hat Linux (6.5-37.el5_2.2rh)
Copyright (C) 2006 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/libthread_db.so.1".


warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./max'.
Program terminated with signal 11, Segmentation fault.
#0 0x080483ef in main () at maxusermem.c:15
15 *scan_ptr='\0';
(gdb) bt
#0 0x080483ef in main () at maxusermem.c:15
(gdb)

prof/gprof를 이용하여 서브함수별 속도를 나타냄
gcc -pg -o program program.c
./program
ls -la하면 gmon.out이 생김

메모리 디버깅(malloc와 free 이용할 때 사용)
gcc -o test test.c -lefence
./test
gdb test
(gdb) run

valgrind => 가장 좋은 디버거
$ valgrind --leak-check=yes -v ./test

댓글 없음:

댓글 쓰기