version 23, including all changes.
.
Rev |
Author |
# |
Line |
21 |
JohnMcPherson |
1 |
You might also be interested in the CommonProgrammingBugs page. Beware of [HeisenBug]s. If you aren't a programmer, you can help by WritingBugReports. |
17 |
JohnMcPherson |
2 |
|
|
|
3 |
---- |
|
|
4 |
!Contents |
|
|
5 |
|
20 |
JohnMcPherson |
6 |
* gcc compile-time options |
17 |
JohnMcPherson |
7 |
* GDB |
|
|
8 |
* strace |
|
|
9 |
* signals |
|
|
10 |
* Core files |
|
|
11 |
* Debugging running processes |
|
|
12 |
* Other tools/commands |
20 |
JohnMcPherson |
13 |
|
|
|
14 |
---- |
|
|
15 |
!! [GCC] Compile Options |
|
|
16 |
* have -g in your CFLAGS (for [C]) or CXXFLAGS (for [C++]) environment variable so that debugging symbols are stored in your binary objects. |
|
|
17 |
* Compile with -Wall to get all 'standard' compiler warnings. |
|
|
18 |
* Compile with -Wshadow to get a warning when you declare a variable with the same name as one in an outer scope. |
|
|
19 |
* If you are using the GNU C library (eg linux systems), you can #include <mcheck.h> to get some extra debugging for malloc(3) - see the [mcheck] page |
17 |
JohnMcPherson |
20 |
|
|
|
21 |
---- |
|
|
22 |
!! [GDB] |
|
|
23 |
|
|
|
24 |
Debugging under Linux is done mostly by using gdb(1). |
|
|
25 |
|
|
|
26 |
If you want to debug a program: |
|
|
27 |
# Compile it with debugging support. This is done by adding the -g option to the gcc(1) command line. If you are using make(1), you can export CFLAGS=-g, you should also set -Wall too, but only because it's a good idea in general. An example: gcc -g -Wall foo.c -o foo |
|
|
28 |
# Load your program in gdb: "gdb ./''programname''" |
|
|
29 |
# type "run" at the prompt to run the program. |
|
|
30 |
# when the program crashes you should be able to type "bt full" to get a full backtrace of what the program was doing at the time. |
|
|
31 |
|
|
|
32 |
!!useful gdb(1) commands: |
|
|
33 |
;bt full: give a complete backtrace of a program. If a program crashes __this__ is what the programmer will want from you. |
|
|
34 |
;print: This lets you print out various expressions, eg: "print node" "print *node" "print node->key" "print node->next->key" etc. |
|
|
35 |
;break: This lets you set breakpoints at functions or lines in the source code, eg: "break main" or "break sourcefile.cpp:55". This can be abbreviated as just "b". |
|
|
36 |
;run: run a program up until it encounters a break point or completes. |
|
|
37 |
;cont: start running from the current command until the next break point or the end. |
|
|
38 |
;step: step to the next command, or into a function call (ie go to the instructions within that function). |
|
|
39 |
;next: step to the next command, or over a function call (ie treat the call as a single command) |
|
|
40 |
;frame: change which frame you are working on. eg: "frame 1" will change the scope to frame 1. |
22 |
IanMcDonald |
41 |
|
|
|
42 |
For a little more info see http://wand.net.nz/~iam4/208/gdb.html |
17 |
JohnMcPherson |
43 |
|
20 |
JohnMcPherson |
44 |
---- |
17 |
JohnMcPherson |
45 |
!!Other useful debugging tricks and traps: |
|
|
46 |
!strace |
|
|
47 |
strace(1) lets you see what a program is doing in a coarse kind of way, if you think strace(1) is too quiet, perhaps ltrace(1) is for you. for the bsdites amongst us, I believe these are called struss(1) and sotrace(1). [Darwin] ([MacOSX]) has ptrace and ktrace (and kdump to read the created file). |
|
|
48 |
|
|
|
49 |
The command for this is: |
21 |
JohnMcPherson |
50 |
<verbatim> |
17 |
JohnMcPherson |
51 |
strace ''programname'' |
21 |
JohnMcPherson |
52 |
</verbatim> |
17 |
JohnMcPherson |
53 |
if the program is already running: |
21 |
JohnMcPherson |
54 |
<verbatim> |
17 |
JohnMcPherson |
55 |
strace -p ''pid'' |
21 |
JohnMcPherson |
56 |
</verbatim> |
17 |
JohnMcPherson |
57 |
will also work. |
|
|
58 |
|
|
|
59 |
!signals |
19 |
PerryLorier |
60 |
If your program hangs, you can press Alt-\ to send it a [SIGQUIT] and force it to dump core. You can also force them to dump core with the command: |
21 |
JohnMcPherson |
61 |
<verbatim> |
17 |
JohnMcPherson |
62 |
kill -QUIT ''programpid'' |
21 |
JohnMcPherson |
63 |
</verbatim> |
17 |
JohnMcPherson |
64 |
|
|
|
65 |
!Core files |
|
|
66 |
To allow crashing programs to create [CoreDump]s you have to remove the ulimit(1) on them. This can be done with the command: |
21 |
JohnMcPherson |
67 |
<verbatim> |
17 |
JohnMcPherson |
68 |
ulimit -c unlimited |
21 |
JohnMcPherson |
69 |
</verbatim> |
17 |
JohnMcPherson |
70 |
Note, this is for the shell (and all its children) only. |
|
|
71 |
|
|
|
72 |
By default core files are placed in the working directory (often the same directory the executable is in). This may not be ideal for you if the executable is on a read only file system. To change this behaviour you can use the following command. |
21 |
JohnMcPherson |
73 |
</verbatim> |
17 |
JohnMcPherson |
74 |
echo /var/cores/core.%e.%p >/proc/sys/kernel/core_pattern |
21 |
JohnMcPherson |
75 |
</verbatim> |
17 |
JohnMcPherson |
76 |
%e is replaced by the executable name and %p is replaced by the pid of the process. For more possible replacements see fs/exec.c in your nearest kernel source. |
|
|
77 |
|
|
|
78 |
gdb(1) can also do postmortem analysis on core files like so: |
21 |
JohnMcPherson |
79 |
<verbatim> |
17 |
JohnMcPherson |
80 |
gdb ./''program'' ./''corefile'' |
21 |
JohnMcPherson |
81 |
</verbatim> |
17 |
JohnMcPherson |
82 |
If you run gdb(1) on your program and it displays the names of the functions but doesn't display their types (eg: what arguments they have or line number information) you probably didn't compile them with "-g". |
|
|
83 |
|
|
|
84 |
! modifying a running process |
|
|
85 |
You can use gdb to attach to a currently running process. For example, to change where its stderr is going: |
21 |
JohnMcPherson |
86 |
<verbatim> |
17 |
JohnMcPherson |
87 |
$ gdb <executable> <process_id> |
|
|
88 |
(gdb) call close(2) |
|
|
89 |
$1 = 0 |
|
|
90 |
(gdb) call open("/tmp/prog-debug", 0101) |
|
|
91 |
$2 = 2 |
|
|
92 |
(gdb) cont |
21 |
JohnMcPherson |
93 |
</verbatim> |
17 |
JohnMcPherson |
94 |
Note that the octal 0101 stands for O_CREAT|O_WRONLY, since gdb will complain about no debugging symbols for resolving those words otherwise. Check with your /usr/include files... the c library with debian testing at least has these definitions in /usr/include/bits/fcntl.h. (0100 + 01). |
|
|
95 |
|
|
|
96 |
!Graphical Debuggers |
|
|
97 |
ddd(1) appears to be a reasonable [GUI] interface to gdb(1) for those that are afraid of [CommandLine]s. |
|
|
98 |
|
|
|
99 |
[Insight] is another. |
|
|
100 |
|
|
|
101 |
!assert |
|
|
102 |
use assert(3) everywhere in your source code. It's much nicer at finding your bugs closer to where the bug actually hides. |
|
|
103 |
|
|
|
104 |
!Electric Fence |
|
|
105 |
Make use of electricfence (libefence) for tracking memory allocation errors. In debian this can be enabled on the fly by setting an LD_PRELOAD variable, like so: |
|
|
106 |
|
|
|
107 |
LD_PRELOAD=libefence.so.0.0 your-buggy-programme |
|
|
108 |
|
|
|
109 |
! threads |
|
|
110 |
Note: When using gdb(1) to debug a threaded program, gdb(1) catches two signals ([SIGPWR] & [SIGXCPU]) which are used internally by pthreads on Linux. Use |
21 |
JohnMcPherson |
111 |
<verbatim> |
17 |
JohnMcPherson |
112 |
(gdb) handle SIGPWR pass nostop noprint |
|
|
113 |
(gdb) handle SIGXCPU pass nostop noprint |
21 |
JohnMcPherson |
114 |
</verbatim> |
17 |
JohnMcPherson |
115 |
to stop gdb halting on receiving these signals. |
|
|
116 |
|
|
|
117 |
!!Other useful commands |
|
|
118 |
* catchsegv - prints out the backtrace of function calls for a program receiving a [SIGSEGV]. - don't forget to compile with __-g__ if you want file names and line numbers to be accessible. |
|
|
119 |
* c++filt(1) - reverses the C++ symbol name-mangling that gcc(1) does, so if the program uses c++ then you can read the function names. |
|
|
120 |
|
|
|
121 |
Other neat tools for diagnosing memory errors are: |
|
|
122 |
* [Valgrind] |
|
|
123 |
* electric fence |
|
|
124 |
* [MMGR] (works well with C++) |
|
|
125 |
* [mcheck] (part of libc6-dev) |
|
|
126 |
* [MALLOC_CHECK_] environment variable |
|
|
127 |
* [LD_DEBUG] environment variable |
|
|
128 |
* [DMALLOC|http://www.dmalloc.com] |
|
|
129 |
* printf(3) |
|
|
130 |
* GarbageCollection |
18 |
PerryLorier |
131 |
* AdvancedDebuggingHints |
23 |
JohnMcPherson |
132 |
---- |
|
|
133 |
CategoryProgrammingBugs |