Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2035126
  • 博文数量: 414
  • 博客积分: 10312
  • 博客等级: 上将
  • 技术积分: 4921
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-31 01:49
文章分类

全部博文(414)

文章存档

2011年(1)

2010年(29)

2009年(82)

2008年(301)

2007年(1)

分类: C/C++

2009-03-07 02:58:35

We are going to be using two programs to illustrate how GDB can be used to debug code.

 Debugging a program having a logical error:

The first sample program has some logical errors. The program is supposed to output the summation of (X^0) /0! + (X^1) /1! + (X^2) /2! + (X^3) /3! + (X^4) /4! + ... + (X^n) /n!, given x and n as inputs. However the program outputs a value of infinity, regardless of the inputs. We will take you step by step through the debugging process and trace the errors

     1.  Download the sample program from 

     2.  Compile the program and execute the program.

             g++ broken.c –o broken.

Whatever the input, the output will be inf.

3.     Compile the program on a Solaris/Linux machine using the following command.

g++  broken.c –g –o broken

Remember to compile the program using –g option, this option enables GDB to debug the executable broken.

4.      Start the debugger.

gdb broken

This only starts the debugger; it does not start running the program in the debugger.

5.      Look at the source file broken.c and set a breakpoint in the program in the main function at line 55.

b broken.c : 55   or break broken.c : 55

Line 55 is:

SeriesValue = ComputeSeriesValue(x, n);

 

6.      Let us set an additional breakpoint in the function ComputeSeriesValue() itself  at line 26

b broken.c : 26

Line 23 inside the function ComputeSeriesValue(double x, int n) is:

             factorial = ComputeFactorial( k );

 

7.      Let us set one a breakpoint inside the function ComputeFactorial( int number )at line  11

            b broken.c : 11

Line 11 is:

             fact  = fact * j;

 

8.      Now, we start to run the program in the debugger.

(gdb) run

Note: If we have to supply the command-line arguments for the execution of the program then, we run the program in the debugger as follows:

             run   arg1  arg2   arg3 ….

 

9.      The program starts running and asks us for the input.

Let us enter the values as x=2 and n=3. The expected output value is 5. The following is a snapshot of the program running in the debugger:

(gdb) run

Starting program: /home/csi/d/dave/broken

This program is used to compute the value of the following series:

(X^0)/0! + (X^1)/1! + (X^2)/2! + (X^3)/3! + (X^4)/4! + ... + (X^n)/n!

Please enter the value of x: 2

         Please enter an integer value for n: 3

                        Breakpoint 1, main () at broken.c: 55

55        series Value = ComputeSeriesValue (x, n);

            Note that the program execution stopped at line number 55 (which is where it encounters the first breakpoint).

10.  Now, let us Step Into the function call to ComputeSeriesValue (x=2, n=3). To step into a function call, we use the following command:

 s or step

At this point, the program control is at the first statement of the function ComputeSeriesValue (x=2, n = 3) i.e. at:

 Double series Value = 0.0;

11.  Now, let us run the program in normal speed until it encounters the next breakpoint (or end of main or exit). To do this, we use following command:

continue or c

              Note: That to execute a statement or a function call in a single step, we can use the command next or n. On doing so, the program control will go to the following line.

  Now, the program control will be at:

(gdb) c

Continuing.

Breakpoint 2, ComputeSeriesValue (x=2, n=3) at broken.c: 26

            26                factorial = ComputeFactorial(k);

To display the value of k, we use the following command:

print k or p k

            The resulting output is:

(gdb) p k

$1 = 0

 

12.  Everything has happened as expected up to this point. Now, let’s step intothe function call to ComputeFactorial (k=0) using the step command. To view the contents of the stack, we can use the following command:

bt or backtrace.

                The result of the above command is as follows:

(gdb) backtrace

#0  ComputeFactorial (number=0) at broken.c:8

#1  0x80487a9 in ComputeSeriesValue (x=2, n=3) at broken.c:26

#2  0x80488bf in main () at broken.c:55

 

13.  Now, let us run the program statement by statement printing the values of important variables as we do so.

8         int fact=0 , j=0;

(gdb) n

10        for ( j = 0 ; j <= number ; j++ )

(gdb) n

Breakpoint 3, ComputeFactorial (number=0) at broken.c:11

11          fact = fact * j;

(gdb) p fact

$2 = 0

(gdb) p j

$3 = 0

(gdb) n

13        return fact;

(gdb) p fact

$4 = 0

Note that the function is returning a value of 0 for the function call ComputeFactorial(number=0). This is an ERROR!

            By taking a closer look at the values printed above, you will realize that we are computing “fact=fact * j” where both fact and j have been initialized to 0. We need to initialize fact=1 and j=1. We need to change the following lines:

Line 8 : int fact = 1, j =1;

Line 10 : for( j=1; j <= number ; j++ )

 

    14. Then, recompile the code and run it, you will get the expected output.

 

Debugging a program that produces a core dump

This program causes a core dump due to a segmentation fault. We will try to trace the reason for this core dump.

Download the program, from

 

     1.  Compile the program using the following command.

            g++ testit.c –g –o testit

 

     2.  Run it normally, you should get the following result:

                 Segmentation fault (core dumped)

 

3.      The core dump generates a file called corewhich can be used for debugging. Since, this program is really short, we will not need to set any breakpoints. Use the following command to start running the debugger to debug the core file produced by testit.

     gdb testit core

The output of the above command should look like this:

bash$ gdb testit core

GNU gdb 19991004

Copyright 1998 Free Software ……….…

Core was generated by `testit'.

Program terminated with signal 11, Segmentation fault.

Reading symbols from /usr/lib/libstdc++-libc6.1-1.so.2...done.

Reading symbols from /lib/libm.so.6...done.

Reading symbols from /lib/libc.so.6...done.

Reading symbols from /lib/ld-linux.so.2...done.

#0  0x804851a in main () at testit.c:10

10              temp[3]='F';       

4.      As we can see from the output above, the core dump was produced

      as a result of execution of the statement on line 10: temp[3] =’F’;

    Take a closer look at the declaration of temp on line 5 :

                        Line 5          char *temp = "Paras";

We find that  temp  is a char* which has been assigned a string literal, and so we cannot modify the contents of the literal as on line 10. This is what is causing a core dump





#include <stdio.h>

int main()
{
        char *temp = "Paras";

        int i;
        i=0;

        temp[3]='F';

        for (i =0 ; i < 5 ; i++ )
                printf("%c\n", temp[i]);
}

阅读(1361) | 评论(0) | 转发(0) |
0

上一篇:size_t类型

下一篇:用 GDB 调试程序

给主人留下些什么吧!~~