| Both sides previous revision
Previous revision
Next revision
|
Previous revision
|
programming:debug [2008/10/30 09:21] cyril |
programming:debug [2013/09/19 16:41] (current) |
| ====== Debugging ====== | ====== Debugging ====== |
| ==== Colorgcc ==== | |
| |
| - install colorgcc | If you look directly at gcc output, you should install [[software:colorgcc|ColorGCC]] which displays errors in red and warning in yellow. |
| - make sure ~/bin path is in your $PATH variable before /usr/bin | |
| - place symlinks in ~/bin/:<code> | |
| cc -> /usr/bin/colorgcc | |
| g++ -> /usr/bin/colorgcc | |
| gcc -> /usr/bin/colorgcc | |
| </code> | |
| - create a ~/.colorgccrc file, and define inside the location of the real cc, gcc, g++ binaries:<code> | |
| /usr/bin/cc, gcc, g++ | |
| </code> | |
| | |
| Source: [[http://en.opensuse.org/Libzypp/Devel/colorgcc]] | |
| |
| ==== Segmentation Faults ==== | ===== Segmentation Faults ===== |
| === The crash occurs where the error is === | ==== The crash occurs where the error is ==== |
| |
| It's the simpler case, which fortunately happens (null pointers, etc). | It's the simpler case, which fortunately happens (null pointers, etc). |
| |
| The solution is to use a debugger like GDB to watch variable contents (see [[#gdb_summary]]). | The solution is to use a debugger like [[software:gdb|GDB]] to watch variable contents. |
| |
| You have several possibilities to get into the program where the segfault occurred : | You have several possibilities to get into the program where the segfault occurred : |
| * run the program with gdb | * run the program with [[software:gdb|GDB]] |
| * configure your shell to create a core dump when the program crashes (''ulimit -c unlimited'' for bash and zsh, ''limit coredumpsize unlimited'' for tcsh; the ''file'' command tells you which program created the core dump), and inspect the core dump with gdb. | * configure your shell to create a core dump when the program crashes (''ulimit -c unlimited'' for bash and zsh, ''limit coredumpsize unlimited'' for tcsh; the ''file'' command tells you which program created the core dump), and inspect the core dump with [[software:gdb|GDB]]. |
| * [[howtos-tips#catching_signals|catch the sigsegv signal]] and freeze the program, then attach the debugger to the running program. | * [[howtos-tips#catching_signals|catch the sigsegv signal]] and freeze the program, then attach the debugger to the running program. |
| |
| === The crash does not occur directly === | ==== The crash does not occur directly ==== |
| |
| Then you have to use a memory checker, such as ''valgrind''. The ''memcheck'' tool will tell you about all memory access errors even if they don't throw segfault. | Then you have to use a memory checker, such as [[software:valgrind|Valgrind]]. The ''memcheck'' tool will tell you about all memory access errors even if they don't throw segfault. |
| |
| <code bash> | <code bash> |
| valgrind --tool=memcheck <your-program> <args> | valgrind --tool=memcheck <your-program> <args> |
| valgrind <your-program> <args> | valgrind <your-program> <args> # memcheck is the default tool |
| </code> | </code> |
| |
| | ===== Memory leaks ===== |
| |
| ==== GDB Summary ==== | The solution is again [[software:valgrind|Valgrind]]: |
| | <code bash> |
| | valgrind --leak-check=full <program> <args> |
| | </code> |
| |
| == Starting == | |
| * **# ''gdb <exec-file>''** | |
| * **# ''gdb <exec-file> <core-file>''** : inspect the core dump | |
| * **# ''gdb <exec-file> <pid>''** : attach to the running process | |
| |
| == Running == | |
| * **''run <program-parameters...>''** (short "r") : start the program | |
| * **''step [count]''** (short "s") : step one line | |
| * **''stepi [count]''** (short "si") : step one instruction | |
| * **''next [count]''** (short "n") : step one line without entering in functions | |
| * **''continue''** (short "c") : continue the program | |
| * **''finish''** (short "fin") : execute until selected stack frame returns | |
| * **''advance [source-file]:<line>''** (short "adv") : continue up to the given location | |
| * **''call <func-name>''** (short "ca") : call a function (the context is copied so that it is not modified) | |
| * **''kill''** (short "k") : stop the program | |
| |
| == Navigating == | ===== Errors prevention ===== |
| * **''backtrace''** (short "bt") : show the stack | |
| * **''frame <frame-number>''** (short "f") : move to the stack drame number | |
| * **''list [source-file]:<line|function>''** (short "l") : show source code | |
| | |
| == Threads == | |
| * **''thread <thread-num>''** (short "t") : switch to thread | |
| * **''info threads''** (short "i th") : show list of current threads | |
| | |
| == Breakpoints == | |
| * **''break [source-file]:<line|function> [thread <thread-num>] [if <condition>]''** (short "b") : set a breakpoint | |
| * **''info breakpoints''** (short "i b") : show all current breakpoints | |
| * **''condition <breakpoint-number> <condition>''** (short "cond") : specify the breakpoint to break only if condition is true | |
| * **''delete breakpoints <breakpoint-number>''** (short "del b", "del") : delete a breakpoint | |
| * **''enable/disable <breakpoint-numbers...>''** (short "en" and "dis") : enable or disable some breakpoints | |
| | |
| == Inspecting data == | |
| * **''print <var-name>''** (short "p") : print the value/content of the variable | |
| * **''print *<pointer>@<nelements>''** : print nelements of the array | |
| * **''print/<format> <var-name>''** : print with a certain format (x for hexa, ...) | |
| * **''display <var-name>''** (short "disp") : display the value/content of the variable at every step | |
| * **''awatch <var-name>''** (short "aw") : stops the execution whenever the variable is read or written | |
| * **''watch <cond-on-var>''** (short "wa") : stops the execution whenever the condition on the variable becomes true | |
| * **''ptype <var-name>''** : type of variable | |
| * **''x <addr>''** : print the content of memory, can format with /<format> too | |
| * **''set variable <var-name> = <value>''** : change variable value | |
| | |
| == Files == | |
| | |
| * **''source <file-name>''** : load a set of commands from a file | |
| * You can define macros in ~/.gdbinit | |
| | |
| ==== Errors prevention ==== | |
| |
| It is interesting to know the sooner possible about problems. You should then use the ''assert()'' macro to check all of your parameters or variables that could cause a crash or an error. When debug is not enabled, there will be no code produced and thus no overhead. | It is interesting to know the sooner possible about problems. You should then use the ''assert()'' macro to check all of your parameters or variables that could cause a crash or an error. When debug is not enabled, there will be no code produced and thus no overhead. |
| If you don't want to save core dumps, you can still [[howtos-tips#catching_signals|catch the sigabrt signal]], freeze the program and attach a debugger. You can even unfreeze the program with the debugger (eg by changing a variable content), and continue the program to see what happens. | If you don't want to save core dumps, you can still [[howtos-tips#catching_signals|catch the sigabrt signal]], freeze the program and attach a debugger. You can even unfreeze the program with the debugger (eg by changing a variable content), and continue the program to see what happens. |
| |
| ==== System calls ==== | ===== System calls ===== |
| |
| ''strace'' prints a list of system calls made by the program. | ''strace'' prints a list of system calls made by the program. |
| |
| |
| | ======= Classic compilation errors ======= |
| ====== Classic compilation errors ====== | |
| |
| Or not so classic... | Or not so classic... |