You are on page 1of 4

Finding Errors

57:017, Computers in
Engineering
Using gdb and ddd

Three types of errors

z
z
z

Learning to debug programs efficiently is an


important skill:

z
z
z
z

Can You Find The Errors In


This Program:
/* Program with errors */
#include <stdio.h>;
int main()
{
int integer1, integer2, sum;
/*declaration*/
p intf(Ente fi
printf(Enter
first
st intege
integer\n)
\n) /*p
/*prompt
ompt fo
for fi
first
st inp
input*/
t*/
scanf(%d, integer1); //read integer value into integer1*/
printf(Enter second integer\n); /*prompt for second input*/
scanf(%d, &integer2); /*read integer value into integer2*/
sum = int1 + int2; /*add inputs and assign to sum*/
printf(Sum is %d\n, sum); /*print sum*/
return 0; /*normal termination of program
}

syntax errorscaught by the compiler


run-time errorsnot detected by compiler but cause
program to blow up at run-time
Other logic errorsProgram may run but behave
incorrectlyi.e.
incorrectly
i.e. give wrong results in some cases.

systematic debugging
thorough testing
use of toolse.g. gdb & ddd
avoidance of evolutionary programming

Can You Find The Errors In


This Program:
missing
ampersand

extra
semicolon

/* Addition Program */
#include <stdio.h>;
int main()
{
int integer1, integer2, sum;

missing
semicolon
/*declaration*/

printf(Enter first integer\n) /*prompt for first input*/


scanf(%d, integer1); //read integer value into integer1*/
printf(Enter second integer\n); /*prompt for second input*/
scanf(%d, &integer2); /*read integer value into integer2*/
wrong variable names
sum = int1 + int2; /*add inputs and assign to sum*/
missing comment terminator
printf(Sum is %d\n, sum); /*print sum*/
return 0; /*normal termination of program

Hard to Read. Format your code to make it easier to read and then find errors.
}

What is a Debugger?
z
z

A debugger is a program that runs other programs


A debugger permits the user to have much greater
control over the program
z
z
z
z

z
z

Preparing to use gdb


z

Can stop the program at any time


Can look at the value of any variables
Can step through a program one line at a time
Can identify where errors occur

In some cases, a debugger can help you find errors


in your program much better than just using
printf() statements
The Gnu C programming environment includes a
debugger called gdb
ddd is a graphical user interface to gdb

Your program must be compiled in a special


way for use with the debugger
z

Add -g to the compilation command

Example:
gcc -g -o datagram datagram.c

This tells the compiler to keep some extra


information
z

Where the original .c file is stored

Information about variables

Using the Debugger


z

To run your program in the debugger (in this


example, the program is datagram):

This starts the g


gdb program,
g
but does not yyet start
your program

The run Command


z

gdb datagram

You will see the prompt (gdb) which means the debugger
is waiting for your commands
run, list, break, continue, step, next,
where, print

Simple UseFinding the location


of a segmentation fault

The debugger can be very useful for finding out


where segmentation faults occur
Steps:

z
z

The break command will let you set a place in the


program where the program must stop (a breakpoint)
A breakpoint may be set at a particular line number or at
the beginning of a function
z
z

When the segmentation fault occurs, the program will stop


and youll see the (gdb) prompt
Type the command where which tells where the program
was when it died
This will list the line number where the program was in
each function that was being executed

The break Command

The command break 35 will cause the program to stop when


g
prompt
p
p
line 35 is reached and return to the (gdb)
break average makes the program stop when
the average() function is called

When breakpoint reached, variables may be printed


The program can be resumed with the continue
command

Just like you ran the program as


datagram file.txt

Program will run until it completes (or


crashes)

The list Command

Start up gdb and run the program with run command

Some of the simple commands demonstrated:


z

The run command actually starts your


program just as if you had typed it as a
command
You can also add extra command line
arguments (if your program uses them) e.g.
run file.txt

z
z

The list command lets you look at your source code


from within the debugger
list 50 would list the lines around line 50 in your
original program
list average would list the beginning of the
function called average() in your program
Typing list again will continue to print lines from
where the last list command left off

The print Command


z

When the program is running but has been paused


at a breakpoint, the print command can be used
to examine variables
print outputs the value of any variables of any
type or any expression
z

The command print total would print the value of the


variable total in the current function
print times[3] would print the fourth value in an array
times
print total/size would use the listed variables to
compute the quotient and print the result

The step and next Functions

Example: Finding the source


of a segmentation error
#include <stdio.h>

The commands step and next allow you to


execute the program one line at a time
z
z

Can follow exactly what lines of code are executed


Can examine variables after each line

step executes the current line of code and then

stops
z

int main() {
int a;
setint(&a,
ti t(&
10)
10);
printf("%d\n", a);
int* b;
setint(b, 10);
printf("%d\n", *b);
return 0;

Will step into a function if the function call is encountered

next works like step, except that it never stops


inside another function
z

void setint(int*, int);

Function call is treated as one line to step past

Compile & run this program


l-ecn012% gcc -o seg seg.c
l-ecn012% seg
10
Segmentation fault (core dumped)
l-ecn012%

}
void setint(int* ip, int i) {
*ip = i;
}

Use gdb to find where the error


occurred
l-ecn012% gcc -g -o seg seg.c
l-ecn012% gdb seg
HP gdb 4.5 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x.
Copyright 1986 - 2001 Free Software Foundation, Inc.
Hewlett-Packard Wildebeest 4.5 (based on GDB) is covered by the
GNU General Public License. Type "show copying" to see the conditions to
change it and/or distribute copies. Type "show warranty" for
warranty/support.
..
(gdb) run
Starting program:
/nfs/server01/local/vol10/k/u/kuhl/57_17/Summer05/Examples/seg
10
Program received signal SIGSEGV, Segmentation fault
si_code: 2 - SEGV_ACCERR - Invalid Permissions for object.
0x40009a0:1 in setint (ip=0x0, i=10) at seg.c:18
18
*ip = i;
(gdb) where
#0 0x40009a0:1 in setint (ip=0x0, i=10) at seg.c:18
#1 0x4000900:0 in main () at seg.c:12

Another Example: Using gdb to find a problem with


eof handling
/*This program tokenizes and prints an input file. Each entry in the input file is separated either by a semicolon or
a newline character. The program properly identifies and prints all entries in the file but hangs after printing the
last entry and eventually dies with a segmentation violation. */
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *fp;
char c;
char buff[100];
int i;
if (argc<2) {
printf("data file must be specified as command line argument\n");
}
else {
if ((fp = fopen(argv[1],
fopen(argv[1] "r"))==NULL)
r ))==NULL) {
printf("error opeining file \n");
}
else {
while(!feof(fp)) {
c = fgetc(fp);
i = 0;
while((c != ';')&&(c != '\n')) {
buff[i] = c;
i++;
c = fgetc(fp);
}
buff[i] = '\0';
printf("next string is: %s\n", buff);
}
}
}
return 0;
}

Compile and run the program


l-ecn012% gcc -o eoftest eofTest.c
l-ecn012% eoftest tinydatafile
next string is: Oasis
next string is: Be Here Now
next
t string
t i
i
is: 1997
next string is: 4
next string is: Stand By Me
Segmentation fault (core dumped)

Tokenizes and prints the


data properly but hangs
after printing the last item
and eventually dies with a
segmentation fault

Using gdb to find the error


z

The problem occurs immediately after


printing the last item from the file.
Set a breakpoint at the print statement and
step through the program behavior
immediately after the last item is printed.

gcc g o eofTest eofTest.c


gdb eofTest
HP gdb 4.5 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x.
Copyright 1986 - 2001 Free Software Foundation, Inc.
Hewlett-Packard Wildebeest 4.5 (based on GDB) is covered by the
GNU General Public License. Type "show copying" to see the conditions to
change it and/or distribute copies. Type "show warranty" for warranty/support.
..
(gdb) list 40
35
}
36
buff[i] = '\0';
37
printf("next string is: %s\n", buff);
38
}
39
}
40
}
41
return 0;
42
}
(gdb) break 37
Breakpoint 1 at 0x4000c30:2: file eofTest.c, line 37 from
/nfs/server01/local/vol10/k/u/kuhl/57_17/Summer05/Examples/eofTest.
(gdb) run tinydatafile
Starting program:
/nfs/server01/local/vol10/k/u/kuhl/57_17/Summer05/Examples/eofTest tinydatafile
Breakpoint 1, main (argc=2, argv=0x7ffff3f8) at eofTest.c:37
37
printf("next string is: %s\n", buff);

(gdb) continue
Continuing.
next string is: Oasis
Breakpoint 1, main (argc=2, argv=0x7ffff3f8) at eofTest.c:37
37
printf("next string is: %s\n", buff);
(gdb) continue
Continuing.
next string is: Be Here Now
Breakpoint 1, main (argc=2, argv=0x7ffff3f8) at eofTest.c:37
37
printf("next string is: %s\n", buff);
(gdb) continue
Continuing.
next string is: 1997
Breakpoint 1, main (argc=2, argv=0x7ffff3f8) at eofTest.c:37
37
printf("next string is: %s\n", buff);
(gdb) continue
Continuing.
next string is: 4
Breakpoint 1, main (argc=2, argv=0x7ffff3f8) at eofTest.c:37
37
printf("next string is: %s\n", buff);
(gdb) next
Note: end of file is not detected
next string is: Stand By Me
28 while(!feof(fp)) {
by outer loop after last character
(gdb) print c
is processed. c = \n
$1 = 10 '\n'

A corrected version of eofTest.c


/* This program corrects the error in the program eofTest.c to properly
process the end of file condition. Data files "datafile" or "tinydatafile"
can used as the input file for the program */
#include <stdio.h>
int main(int argc, char
FILE *fp;
char c;
char buff[100];
int i;

(gdb) next
29
(gdb) next
30
(gdb) next
31
(gdb) print c
$2 = -1 '\377'
(gdb) next
32
(gdb) next
33
(gdb) next
34
(gdb) next
31
(gdb) next
32
(gdb) print c
$3 = -1 '\377'
(gdb)

Next read raises eof.


c = -1 (eof)
c = fgetc(fp);
i = 0;
while((c != ';')&&(c != '\n')) {

While loop is entered since


c = -1

buff[i] = c;
i++;
c = fgetc(fp);

fgetc() contnues to read eof(-1).


We are in an infinite loop

while((c != ';')&&(c != '\n')) {


buff[i] = c;

Note that the buffer will


be overrun and eventually
this will lead to a segmentation
fault

For More Information about


using gdb

*argv[]) {

if (argc<2) {
printf("data file must be specified as command line argument\n");
}
else {
if ((fp = fopen(argv[1], "r"))==NULL) {
printf("error opeining file \n");
}
else {
c = fgetc(fp);
while(!feof(fp)) {
i = 0;
while((c != ';')&&(c != '\n')) {
buff[i] = c;
i++;
c=fgetc(fp);
}
buff[i] = '\0';
printf("next string is: %s\n", buff);
c =fgetc(fp);
}
}
}
return 0;

consult the on-line references listed under the


Examples link on the class web site.

You might also like