유닉스프로그래밍및실습 gdb 사용법
fprintf 이용 단순디버깅 확인하고자하는코드부분에 fprintf(stderr, ) 를이용하여그지점까지도달했는지여부와관심있는변수의값을확인 여러유형의단순한문제를확인할수있음 그러나자세히살펴보기위해서는디버깅툴필요 int main(void) { int count; long large_no; double real_no; init_vars(); fprintf(stderr, $$$ %d %ld %lf, count, large_no, read_no); fprintf(stderr, ### %d %ld %lf, count, large_no, read_no); calc_f1(&count, &large_no); fprintf(stderr, @@@ %d %ld %lf, count, large_no, read_no); }
gdb(gnu debugger) 컴파일과정에서반드시 g 옵션사용 $ gcc g test.c o test gdb 실행 $ gdb test gdb 명령으로디버깅 주요지점에 break point 설정 실행시키면정지점에서중지 중단된상태에서주요변수의값확인 프로그램실행계속 한단계씩진행 함수수행후결과값표시 스택추적
gdb 주요명령 명령 약어 설명 attach at 실행중인프로세스에디버거붙이기 backtrace bt 스택추적 (stack trace) 출력 break b 정지점 (break point) 설정 clear 정지점해제 continue c 프로그램실행계속 delete 번호로정지점설정해제 ( 번호생략시전체해제 ) detach 현재실행중인프로세스에서디버거떼기 display 실행을중단할때마다표현값출력 finish 함수끝까지실행하고함수반환값표시 help 도움말출력 jump 특정주소로분기하여실행계속 list 원시코드다음 10줄출력 next n 프로그램한단계수행. 함수인경우함수내부로들어가지않고다음행으로넘어감 print p 표현값출력 run r 현재프로그램을처음부터실행 set 변수값변경 step s 프로그램을다음소스코드가나올때까지실행. 함수일경우함수내부로진입 where w 스택추적출력
gdb 기본이용 (1) 실행 [kgu@lily sample2]$ gdb a.out GNU gdb (GDB) Fedora (7.3.50.20110722-16.fc16) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/kgu/2012u2/ch05/sample2/a.out...done. list 명령실행 list 23 line_sum += data; 24 } 25 26 return line_sum; 27 } 28 29 /******************************************************************************/ 30 int main(void) 31 { 32 pid_t pid = 1;
gdb 기본이용 (2) list 명령실행 list 33 int i; 34 int read_lines; 35 int fd1; 36 int fd2; 37 int fd3; 38 char buffer[buffer_size]; 39 char result[result_size]; 40 char file_name[filename_size]; 41 42 int line_sum; break 명령으로 calc_line_sum 루틴에정지점설정 break calc_line_sum Breakpoint 1 at 0x4009e0: file mp_calc.c, line 18. break 명령으로 60 번째라인에정지점설정 break 60 Breakpoint 2 at 0x400ab7: file mp_calc.c, line 60.
gdb 기본이용 (3) run 명령실행 r Starting program: /home/kgu/2012u2/ch05/sample2/a.out Breakpoint 2, main () at mp_calc.c:60 60 pid = fork(); print 명령으로현재스택내부의변수값등확인 print pid $1 = 1 print read_lines $2 = 32767 print fd1 $3 = 7 print line_sum $4 = 51 break 명령으로 23 번째라인에정지점설정 break 23 Breakpoint 3 at 0x400a19: file mp_calc.c, line 23.
gdb 기본이용 (4) continue 명령으로계속진행 c Continuing. Detaching after fork from child process 8161. Breakpoint 2, main () at mp_calc.c:60 60 pid = fork(); delete 명령으로정지점 2 삭제 delete 2 continue 명령으로계속진행 c Continuing. Detaching after fork from child process 8384. Detaching after fork from child process 8385. Detaching after fork from child process 8386. Detaching after fork from child process 8387. Breakpoint 1, calc_line_sum ( line=0x7fffffffe320 "753 443 469 159 449 819 784 137 803 351\np\r@") at mp_calc.c:18 18 int line_sum = 0;
gdb 기본이용 (5) where 또는 backtrace 명령으로스택추적출력 where #0 calc_line_sum (line=0x7fffffffe320 "753 443 469 159 449 819 784 137 803 351\np\r@") at mp_calc.c:18 #1 0x0000000000400b43 in main () at mp_calc.c:74 backtrace #0 calc_line_sum (line=0x7fffffffe320 "753 443 469 159 449 819 784 137 803 351\np\r@") at mp_calc.c:18 #1 0x0000000000400b43 in main () at mp_calc.c:74 step 또는 next 명령으로다음단계진행 s 21 for (i = 0; i < 10; i++) { s 22 sscanf(&line[i*4], "%d", &data); s Breakpoint 3, calc_line_sum ( line=0x7fffffffe320 "753 443 469 159 449 819 784 137 803 351\np\r@") at mp_calc.c:23 23 line_sum += data; next 21 for (i = 0; i < 10; i++) {
gdb 기본이용 (6) display 명령으로멈출때마다출력할변수지정 display i 2: i = 0 c Continuing. Detaching after fork from child process 9108. Breakpoint 2, main () at mp_calc.c:60 60 pid = fork(); 2: i = 1 1: pid = 9108 quit 명령으로종료 quit A debugging session is active. Quit anyway? (y or n) y [kgu@lily sample2]$ Inferior 1 [process 9501] will be killed.
기본사용법 관심있는함수마지막에서확인하는방법 list 함수이름을수행하여함수마지막줄번호찾기 break 마지막줄번호 수행하여정지점설정 run 수행하면함수마지막줄에서중단 print로함수내부의변수와전역변수값확인 프로그램이죽은경우정확한위치찾기 run 실행하면오류발생한지점에서중단 where명령으로스택추적 list 명령으로프로그램소스확인 프로그램전체를한단계씩실행하면서확인 break main으로정지점설정 run 실행하면 main() 첫번째줄에서중지 step 명령으로한단계씩진행하면서변수확인 (print 또는 display 이용 )