Linux System Programming Debugging Contents Error Debugging 방법 Error의 형태 Code Inspection Trial and Error Instrumentation Controlled Execution Debugging Steps Debugging with gdb © Yigeun Chae. Private propriraty, do not copy Linux System Programming 1. Errors 바라는 대로 이루어 진다면 다 이루어 진다면 세 상은 멋질 것인가 ? 아니면 허무할 것인가 ? 개발한 모든 소프트웨어는 100 line당 2-5개의 error발 생 소프트웨어 Life Cycle중에서 중-하반기 Testing Debugging © Yigeun Chae. Private propriraty, do not copy Linux System Programming Error의 형태 Specification Error (사양에러) Design Error(설계에러) 소프트웨어 설계 이전 요구사항파악 단계에서 잘 못된 오류 파급효과 큼 상위설계, 상세설계, 시험설계 등에서 비롯된 오류 상위 설계일수록 파급 효과 큼 Coding Error 모든 프로그래머는 실수할 개연성 있음 심리적 압박감이 고조되는 시기 스스로 디버깅을 함으로 극복 가능함 © Yigeun Chae. Private propriraty, do not copy Linux System Programming Source Code측면에서 Bugs Syntax errors Build errors Makefiles에 의해 도움 받을 수 있음 Semantic errors compiler에 의해 확인 변수의 초기화 실패, dead code, data type 오류 Wrong variables, pointer errors Bug 수정 Bug 수정시 수정한 코드에는 반드시 수정사항을 comments 처리 하고 Testing Bug이 코드 작성시 error인지 알고리즘 error 인지 확인해야 함. © Yigeun Chae. Private propriraty, do not copy Linux System Programming Bug 수정 Bug 수정시 수정한 코드에는 반드시 수정사항을 comments 처리 하고 Testing Bug이 코드 작성시 error인지 알고리즘 error 인지 확인해 야 함. © Yigeun Chae. Private propriraty, do not copy Linux System Programming Error 줄이는 요령 Dry Running or Code walkthru(가상 실행) Prototype code 작성 중요 알고리즘 따라 가보기 도상 실행 새로운 기능을 구현 할 때 우선 코드 작성 패키지 활용 이나 API 이용 방법 터득 실제 효과 큼 with Suspicion, with consideration without unbelief © Yigeun Chae. Private propriraty, do not copy Linux System Programming 일반적인 디버깅 단계 테스트 안정화 버그의 위치 탐색 수정 버그를 반복 가능한 상태로 고정 구역화 결함이나 버그의 존재 확인 코드 수정 검증 수정된 코드를 포함한 동작 상태 점검 © Yigeun Chae. Private propriraty, do not copy Linux System Programming 일반적인 디버깅 방법 1 Code Inspection Trial and Error Instrumentation 보조코드 첨가 #ifdef DEBUG ……. #endif Controlled execution Using Debugging Tools © Yigeun Chae. Private propriraty, do not copy Linux System Programming 일반적인 디버깅 방법 2 printf() debugging 가장 일반적이지만 출력이 비교적 느리다 Ad-hoc code addition & removal standard output 은 메시지를 보관 할 수 없다. 해결책: Use macros to encapsulate debug printf’s stderr() 를 debugging output으로 사용 Assertions In C/C 코드중에서 특정 포인트를 평가(evaluate) 하여 true일 경우 계속 실행 false일 경우 실행 중단하고 문제를 display #include <assert.h> assert(statement); © Yigeun Chae. Private propriraty, do not copy Linux System Programming Playing with error(1) No error codes typedef struct { char *data; int key; } item; for(; i < n && s != 0; i++) { s = 0; for(j = 0; j < n; j++) { if(a[j].key > a[j+1].key) { item array[] {"bill", {"neil", {"john", {"rick", {"alex", }; = { 3}, 4}, 2}, 5}, 1}, sort(a,n) item *a; { int i = 0, j = 0; int s = 1 item t = a[j]; a[j+1] = t; s++; } } n--; } } main() { sort(array,5); } © Yigeun Chae. Private propriraty, do not copy a[j] = a[j+1]; Linux System Programming Playing with error(2) 컴파일 하면 성공 main() : 아래 코드로 변경하면 ?? main() { int i; sort(array,5); for(i = 0; i < 5; i++) printf("array[%d] = {%d, %s}\n", i, array[i].key, array[i].data); } © Yigeun Chae. Private propriraty, do not copy Linux System Programming Playing with error(3) 컴파일 하면 성공 실행시키면 ? OS에 따라 segmentation fault 가능 배열의 마지막 문자 참조 불가능의 원인 Null Pointer 참조 ! typedef struct { char data[4096]; /* 변경 */ int key; } item; 거의 모든 리눅스에서 오류 가능성 © Yigeun Chae. Private propriraty, do not copy Linux System Programming Code Analysis 예상대로 동작하지 않을 때 코드 분석 발생 가능성 있는 곳의 점검 변수의 초기화 실패 점검 조건문에서 기호 사용 오류 혹은 서술 오류 점검 컴파일러 동작시 가능 혹은 lint LClint 이용 gcc –Wall –pedantic ansi 특히 –Wall 옵션은 필히 사용 ! © Yigeun Chae. Private propriraty, do not copy Linux System Programming Instrumentation (보조코드) 프로그램 동작시 더 많은 정보 수집 위한 코드 첨가 일반적으로 test printf문 사용 error 제거후 수작업으로 모은 test printf문 제거 해야 함 더 편하고 확장된 방법이 바로 보조코드 두가지 방법 C 선행 처리기 사용 printf 사용 © Yigeun Chae. Private propriraty, do not copy Linux System Programming Instrumentation (보조코드) C 선행처리기법 #ifdef DEBUG printf(“Variable x has value = %d\n”, x); #endif Compile Option (definition) –DDEBUG gcc –o testrun –DDEBUG testrun.c 혹은 확장된 방법 #define BASIC_DEBUG 1 #define EXTRA_DEBUG 2 #define SUPER_DEBUG 4 #if (DEBUG & EXTRA_DEBUG) printf…. #endif © Yigeun Chae. Private propriraty, do not copy Linux System Programming C 선행처리기의 MACRO 더욱 확장된 기능이 필요하면 MACRO이용 Macro _LINE_ _FILE_ _DATE_ _TIME_ description 현재 문장 번호를 표현하는 10진 상수 현재 파일 이름을 표현흔 스트링 mm dd yyyy 형식의 현재 날짜 스트링 hh:mm:ss 형식의 현재 시간 스트링 © Yigeun Chae. Private propriraty, do not copy Linux System Programming Debugging Information #include <stdio.h> int main() { #ifdef DEBUG printf("Compiled: " __DATE__ " at " __TIME__ "\n"); printf("This is line %d of file %s\n", __LINE__, __FILE__); #endif printf("hello world\n"); exit(0); $ gcc –o cinfo –DDEBUG cinfo.c $./cinfo Compiled:….. This is line 7 of file cinfo.c hello world $ © Yigeun Chae. Private propriraty, do not copy Linux System Programming Controlled Execution Debugging 코드를 실행 하면서 변수, 알고리즘에 대한 동작 상태를 실시간으로 점검 Debugger(Debugging Tools)를 이용해야 함 소스코드 상태에서 디버깅 adb, sdb, dbx dbx, gdb(GNU) gdb의 변형판 : xxgdb, tgdb, DDD Emancs에서는 프로그램 편집상태에서 gdb-mode 실행가능 컴파일 option 사용 gcc -g © Yigeun Chae. Private propriraty, do not copy Linux System Programming 그외 Debugging 방법 Editors Version control Memory allocation tools System call tracers © Yigeun Chae. Private propriraty, do not copy Linux System Programming Editors editor를 이용한 degugging 방법은 프로그래밍 에러를 초기 에 줄일 수 있다. 방법 Syntax highlighting (gvim, ultra editor , winedt) Brace matching( % in gvim) Automatic indentation(미리 설정) © Yigeun Chae. Private propriraty, do not copy Linux System Programming Version control version control tool(RCS, CVC, SCCS)를 사용하는 group developing 의 경우 효과 있음. 일반적으로 Version control은 bug tracking software와 함 께 사용하는 경우가 많음 © Yigeun Chae. Private propriraty, do not copy Linux System Programming Core dumps core dump는 프로그램이 동작중 여하한 이유로 인하여 더 이상 수행이 불가능하여 OS에 의하여 중단하면서 생성 중단 시점의 프로세스에서 사용한 memory의 snapshot, stack trace, 변수의 값들을 포함한다. 이는 debugger를 사용할 때 중요한 debugging 정보가 됨. Debugger에서는 memory contents를 볼 수 있음. © Yigeun Chae. Private propriraty, do not copy Linux System Programming Memory allocation tools C 와 C++ 의 경우 포인터 변수 사용에 실수가 많다. 이는 Memory corruption 과 pointer misuse 때문 Memory 할당을 모니터링하는 도구를 사용하면 debugging 이 용이 해 짐 이 도구들은 메모리관련 함수들을 library형태로 제공하고 boundary checking하는 기능을 포함한다. © Yigeun Chae. Private propriraty, do not copy Linux System Programming System call tracers system call tracer는 프로그램에서 사용되는 system calls 를 모니터링 HW접근 혹은 OS에서 관리하는 자원들을 접근하는 system calls를 관리 binary code와 함께 동작하며, source code의 언어와 무관 하게 동작 © Yigeun Chae. Private propriraty, do not copy Linux System Programming GDB gdb(GNU Debugger)는 표준의 무료 debugging 도구 C, C++, Pascal, Objective-C등의 언어 지원 사용 가능 OS: Unix, Linux, MS Windows Sites: http://www.gnu.org/software/gdb/ © Yigeun Chae. Private propriraty, do not copy Linux System Programming Using GDB 사용전 compile때 debugging flags 이용 ! gcc -g debug_me.c -o debug_me 실행방법: gdb debug_me gdb debug_me core © Yigeun Chae. Private propriraty, do not copy Linux System Programming Using GDB – run & breakpoints 코드의 실행 run 실행중 break break break break 의심스러운 지점에 stop하는 방법 [file:]function - set breakpoint class::member_fn debug_me.c:9 (break on line 9) main (break on function main) 코드 보기 list © Yigeun Chae. Private propriraty, do not copy Linux System Programming Using GDB – stepping 코드의 단계적 실행 next, n : 1라인 실행 후 중단, 함수는 바로 실행(1라인처 럼) step, s : next와 유사, 함수의 경우 함수속으로 가 서 중단 사용법 보기 Help -all © Yigeun Chae. Private propriraty, do not copy Linux System Programming Using GDB – printing 변수의 현재 값을 알고 싶을 때 print var 변수에 대하여 expressions, casts, and functions 가능 print i*2 print argv[argc] © Yigeun Chae. Private propriraty, do not copy Linux System Programming Using GDB : Commands bt continue, c watch info locals - print function stack continue execution watch an expr local variables © Yigeun Chae. Private propriraty, do not copy Linux System Programming GDB Command Collection quit : Quits gdb and returns back to the user prompt. run : Starts the execution of the program being debugged. control-c : Interrupts the execution of the program being debugged. This is useful if the program appears to be stuck in a loop. where : Shows where the program was stopped. A trace showing each active function's argument list, the file that the function came from, and the next line in the code that will be executed in the function is displayed. up : Moves up the trace to function that called the current function. down : Moves down the trace to function that is called by the current function. print c : Prints out value of the variable c. print c+x : Prints out value of the sum of the variables c and x. Note that any regular C expression can be evaluated by print. list : Show source code around place that program is currently stopped. break #line-number : Sets a breakpoint at the specified line number of the file. break [file:]function : Sets a breakpoint at the specified function of the file. info breakpoints : Show the status of user-settable breakpoints clear : Removes the breakpoint cont : Continues the execution of a program after a control-c or a break point. step : Executes a single statement of program and returns to the debugger. set args: Specify the arguments to be used the next time your program is run. next : Executes a subroutine and treats it as one instruction. debugger. © Yigeun Chae. Private propriraty, do not copy Linux System Programming Graphical tools - DDD DDD(Data Display Debugger) GDB기능을 그래픽 인터페이스로 보여줌 자료구조를 쉽게 볼 수 있는 장점이 있음. © Yigeun Chae. Private propriraty, do not copy Linux System Programming Profiling Popular tools for profiling: gprof 복잡한 프로그램의 경우 혹은 다른 사람의 프로그램 분석시 함수의 call tracing이 상당히 유용 Call graph: 어떤 함수를 어떻게 call했는지 알 수 있음 Use cc/cpp options: -pg –a 컴파일 코드 수행 후 outputs gmon.out & bb.out 생성 grof 동작 및 분석 to analyze gcov Test coverage © Yigeun Chae. Private propriraty, do not copy Linux System Programming More tools 또 다른 그래픽 디버깅 도구 xxgdb : front end to gdb GNU Visual Debugger 메모리 디버깅 도구 Electric fence – memory debugger Checker – runtime memory checker © Yigeun Chae. Private propriraty, do not copy Linux System Programming