EE485 DebuggingTechniques
EE485 DebuggingTechniques
3
Language Features May Help (or Not)
• Language features that prevent bugs
• Range checking of array subscripts
• Restricted pointers (or no pointers)
• Garbage collection
• String data types
• Strong type checking
4
Bugs
• What if my program crashes, prints nonsense, or hangs forever?
• Novice programmers? blame compilers, libraries, anything other than my code
• Experienced programmers? most problems are likely to be their fault
5
Easy Bugs – Common Bugs
(1) Look for common patterns
int main()
{ printf(“%d %f”, n, d);
int n;
double d = 3.14;
printf("%d %f\n", d, n);
scanf("%d", n); scanf(“%d”, &n);
return 0;
}
6
Easy Bugs - Program Hangs Forever or Crashes
(2) Program hangs or crashes? Get the stack trace & where!
$ gdb yourprog
(gdb) run
^C You need to type Ctrl+C to stop the program
Program received signal SIGINT, Interrupt.
(gdb) where
#0 __GI___libc_read (fd=0, buf=0x8402470, nbytes=512) at ../sysdeps/unix/sysv/linux/read.c:27
#1 _IO_new_file_underflow (fp=0x7fffff3eba00 <_IO_2_1_stdin_>) at fileops.c:531
#2 __GI__IO_default_uflow (fp=0x7fffff3eba00 <_IO_2_1_stdin_>) at genops.c:380
#3 _IO_vfscanf_internal (s=<>, format=<>, argptr=argptr@entry=0x7ffffffee220, errp=errp@entry=0x0)
at vfscanf.c:630
#4 __isoc99_scanf (format=<optimized out>) at isoc99_scanf.c:37 Program hangs waiting for input
#5 main () at test.c:9
Similarly, you can easily find out where the program crashes
$ gdb yourprog
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0x00007fffff06f8c2 in _IO_vfscanf_internal (s=<…>, format=<…>, argptr=…, errp=…) at vfscanf.c:1898
(gdb) where
#0 _IO_vfscanf_internal (s=<…>, format=<…>, argptr=…, errp=…) at vfscanf.c:1898
#1 __isoc99_scanf (format=<optimized out>) at isoc99_scanf.c:37
#2 main () at test.c:9
7
Debugging with Core Dump
• Sometimes, your program doesnot crash only when it runs with gdb
• Why? running with gdb incurs some overhead, which might make the program
avoid the crashing course
• Run the program without gdb and make it crash with a core dump
• Core dump: a binary file that contains the program state at the time of crash
$ ./myprog
…
Segmentation fault (core dumped)
$ ulimit -a
…
core file size (blocks, -c) 0 Core dump file size is set to 0; disabled!
…
8
Debugging with Core Dump
• Enable core dump file: set its file size large enough
• How large? Depends on your program size, but 10MB is enough for most cases
$ ulimit –c 10000000
$ ulimit –a
…
core file size (blocks, -c) 10000000
…
9
Gdb with core in eelab machines
10
Other Ways to Deal with Bugs
(3) Read before typing– resist the urge to start typing
• Hastily changing the code to see if it fixes the code would waste time
• That could introduce new bugs without fixing the original ones
• Take a break, and return - what you currently see may be what you meant, not
what you wrote!
11
Dealing with Difficult Bugs
• Sometimes you have no clue on what’s going on!
(1) Make the bug reproducible
• Bugs that do not manifest often are hard to debug
• See if you can construct input/parameters to reproduce the bug “reliably”
12
Dealing with Hard Bugs
(4) Display output to localize your search
• Display more information (e.g., print “can’t get here”, if it should be impossible
to reach here – you can set up a breakpoint to inspect further)
• Display message in a compact fixed format – easy to find a pattern by eye or
grep (e.g., format the value in the same way – %x or %p in C/C++)
(5) Add self-checking code
• Write a check function to see whether some code leads into a weird state
• Leave the check code even after debugging (e.g., #ifdef DEBUGX … #endif)
check(“before suspect”);
/* … suspect code … */
check(“after suspect”);
13
What If Nothing Works?
• What if your logic is plain wrong, but you don’t realize it’s wrong?
• Debugger (gdb) might help to elucidate the errors in your mental model
• Misconception
• Operator precedence, wrong operator, wrong indentation
• Local variable that hides a global name (or global variable in local scope)
14
Non -reproducible Bugs
• Non-deterministic manifestation of bugs
• Not likely to be a bug in your algorithm
• Your code might be using information that changes each time the program runs
15
Non -reproducible Bugs
• Crashes in the middle of nowhere?
• Far away from anything that could be wrong
• Most likely problem is overwriting memory that isn’t used until much later
• Or return an address of a local variable as a pointer – recipe for delayed disaster!
16
Debugging Memory Management
17
Debugging Memory Management (cont.)
int *p;
… Dangling pointer
p = (int*)malloc(sizeof(int));
…
free(p);
…
*p = 5;
18
Debugging Memory Management (cont.)
int *p;
…
p = (int*)malloc(sizeof(int));
Multiple free
…
free(p); Detection: man malloc,
…
free(p); MALLOC_CHECK_
19
Debugging Memory Management (cont.)
double *p;
Allocating too few bytes
p = (double*)malloc(sizeof(double*)); on 32-bit OS.
On 64-bit OS, malloc()
allocates 8 bytes (no problem)
20
Debugging Memory Management (cont.)
• Segmentation fault? Make it happen within gdb, and then issue the gdb
“where” command. The output will lead you to the line that caused the fault.
(But that line may not be where the error resides.)
• Manually inspect each call of malloc(), calloc(), and realloc() in your code,
making sure that it allocates enough memory
• Temporarily hardcode each call of malloc(), calloc(), and realloc() such that it
requests a large number of bytes. If the error disappears, you'll know that at
least one of your calls is requesting too few bytes
21
Debugging Memory Management (cont.)
• Temporarily comment- out each call of free() in your code.If the error
disappears, then you'll know that you're freeing memory too soon, freeing
memory that already has been freed, or freeing memory that should not be
freed, etc.
22
Assignment for Lecture 6
• Due Next Friday 10:25AM
• This homework is open-ended, and there’s no “right” answer
• As long as you submit the homework with relevant comments, you’ll get full credit!
• Homework description:
• If you take EE209, share with us your debugging experience for assignment 2 of
EE209. Did you use gdb? If so, briefly explain why you used it and if it was useful to
debug it with gdb. Point out any techniques in Lectures 5 or 6 that were useful in
doing assignment 2 of EE209. If you did not use gdb, explain why not. Explain any
non-gdb techniques that were useful to debug your assignment code.
• If you do not take EE209, please point out what techniques in Lectures 5/6 would
be most useful to you, and explain why. If you have any recent C
programming/debugging experience, explain what was the most difficult in terms of
debugging. Any relevant story is fine.
• Write your comments into a PDF file (named YourStudentID.pdf)
23
24