Difference between revisions of "Remote Debugging with GDB"

From Gumstix User Wiki
Jump to: navigation, search
(New Debugging Tutorial)
 
(New Debugging Tutorial)
Line 5: Line 5:
 
: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:
 
: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:
  
# Download the sample program [www.brokenprogram.com]
 
  
# Compile the program and execute the program.
+
 
 +
1. Download the sample program [www.brokenprogram.com]
 +
 
 +
 
 +
2. Compile the program and execute the program.
  
 
  root@overo:~# g++ -g broken.cpp -o broken  <enter>
 
  root@overo:~# g++ -g broken.cpp -o broken  <enter>
 
  root@overo:~# ./broken  <enter>
 
  root@overo:~# ./broken  <enter>
  
hint: Do not type “g++ -o broken broken.cpp”
 
  
# In this program no matter the input the output always is infinity. The -g option is important because it enables meaningful GDB debugging. Start the debugger
+
:hint: Do not type “g++ -o broken broken.cpp”
  
 +
 +
3. In this program no matter the input the output always is infinity. The -g option is important because it enables meaningful GDB debugging.  Start the debugger
 +
 +
 
  root@overo:~# gdb broken <enter>
 
  root@overo:~# gdb broken <enter>
  
# This only starts the debugger; it does not start running the program in the debugger. Look at the source :code and set a breakpoint at line 43  
+
 
:(if GDB is not your command line, i.e. (gdb), type) -->  gdb
+
4. This only starts the debugger; it does not start running the program in the debugger. Look at the source code and set a breakpoint at line 43  
 +
(if GDB is not your command line, i.e. (gdb), type) -->  gdb
 
 
 
 
Complete the following steps
+
:Complete the following steps
  
 +
 
  (gdb) b 43
 
  (gdb) b 43
 +
 +
  
 
Doing that will make this appear below
 
Doing that will make this appear below
Line 30: Line 40:
  
 
    
 
    
# Now, we start to run the program in the debugger.
 
  
 +
5. Now, we start to run the program in the debugger.
 +
 +
 
  (gdb) run
 
  (gdb) run
  
# Note: If you still need to supply the command-line arguments for the execution of the program, simply include them after the run command, just as normally done on the command line. The program starts running and asks us for the input.
+
 
 +
 
 +
6. Note: If you still need to supply the command-line arguments for the execution of the program, simply include them after the run command, just as normally done on the command line. The program starts running and asks us for the input.
 +
 
  
 
:HINT: if you left any commands out before or want to put one in, do it now
 
:HINT: if you left any commands out before or want to put one in, do it now
  
Let's 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:
+
 
 +
Let's 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:
 +
 
  
 
:This program is used to compute the value of the following series :  
 
:This program is used to compute the value of the following series :  
Line 54: Line 73:
 
    
 
    
  
# Note that the program execution stopped at our first (and only) breakpoint. Step into the ComputeSeriesValue() function
+
7. Note that the program execution stopped at our first (and only) breakpoint. Step into the ComputeSeriesValue() function
 
        
 
        
 
To step into a function call, we use the following command:
 
To step into a function call, we use the following command:
Line 60: Line 79:
 
  (gdb) step
 
  (gdb) step
  
 +
 
  ComputeSeriesValue (x=2, n=3) at broken.cpp:17
 
  ComputeSeriesValue (x=2, n=3) at broken.cpp:17
 
  17  double seriesValue=0.0;
 
  17  double seriesValue=0.0;
  
# At this point, the program control is at the first statement of the function ComputeSeriesValue (x=2, n=3) Next let's step through the program until we get into ComputeFactorial.
+
 
 +
8. At this point, the program control is at the first statement of the function ComputeSeriesValue (x=2, n=3) Next let's step through the program until we get into ComputeFactorial.
 
To stay on track follow these commands carefully.
 
To stay on track follow these commands carefully.
 
        
 
        
Line 75: Line 96:
 
  ComputeFactorial (number=0) at broken.cpp:7
 
  ComputeFactorial (number=0) at broken.cpp:7
 
  7  int fact=0;
 
  7  int fact=0;
 +
  
 
:Note: Step lets you get a closer look at each function and line, while next skips over whole functions to the next one.  
 
:Note: Step lets you get a closer look at each function and line, while next skips over whole functions to the next one.  
 +
  
 
:Here we use n and s instead of next and step, respectively. If the command is simply a repeat of the previous command, you can just hit return, which will execute the last command. Finally, we step (with s) into ComputeFactorial(). (If we'd used next, it would have stepped over ComputeFactorial.)
 
:Here we use n and s instead of next and step, respectively. If the command is simply a repeat of the previous command, you can just hit return, which will execute the last command. Finally, we step (with s) into ComputeFactorial(). (If we'd used next, it would have stepped over ComputeFactorial.)
 
    
 
    
# Where are we?
+
 
 +
9. Where are we?
 +
 
  
 
:If you want to know where you are in the program's execution (and how, to some extent, you got there), you can view the contents of the stack using the backtrace command as follows:
 
:If you want to know where you are in the program's execution (and how, to some extent, you got there), you can view the contents of the stack using the backtrace command as follows:
Line 93: Line 118:
 
    
 
    
  
# Watching changes We can step through the program (using the next command) and examine the values using the print command.
+
 
 +
10. Watching changes We can step through the program (using the next command) and examine the values using the print command.
  
  
 
:Once again, follow these commands carefully in order to stay on track.
 
:Once again, follow these commands carefully in order to stay on track.
 +
     
 
       (gdb) next
 
       (gdb) next
 
       9  for (int j = 0; j <= number; j++) {
 
       9  for (int j = 0; j <= number; j++) {
Line 111: Line 138:
 
        
 
        
 
:Try to find the error.
 
:Try to find the error.
 +
 
::HINT: Look inside the “print fact” command
 
::HINT: Look inside the “print fact” command
  

Revision as of 10:29, 27 July 2010

Tutorial for Debugging a program with a logical error

This 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 [www.brokenprogram.com]


2. Compile the program and execute the program.

root@overo:~# g++ -g broken.cpp -o broken  <enter>
root@overo:~# ./broken  <enter>


hint: Do not type “g++ -o broken broken.cpp”


3. In this program no matter the input the output always is infinity. The -g option is important because it enables meaningful GDB debugging. Start the debugger


root@overo:~# gdb broken <enter>


4. This only starts the debugger; it does not start running the program in the debugger. Look at the source code and set a breakpoint at line 43 (if GDB is not your command line, i.e. (gdb), type) --> gdb

Complete the following steps


(gdb) b 43


Doing that will make this appear below

double seriesValue = ComputeSeriesValue(x, n);


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


(gdb) run


6. Note: If you still need to supply the command-line arguments for the execution of the program, simply include them after the run command, just as normally done on the command line. The program starts running and asks us for the input.


HINT: if you left any commands out before or want to put one in, do it now


Let's 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:


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.cpp:43
43  double seriesValue = ComputeSeriesValue(x, n);


7. Note that the program execution stopped at our first (and only) breakpoint. Step into the ComputeSeriesValue() function

To step into a function call, we use the following command:

(gdb) step


ComputeSeriesValue (x=2, n=3) at broken.cpp:17
17  double seriesValue=0.0;


8. At this point, the program control is at the first statement of the function ComputeSeriesValue (x=2, n=3) Next let's step through the program until we get into ComputeFactorial. To stay on track follow these commands carefully.

(gdb) next
18  double xpow=1;
(gdb) n
20  for (int k = 0; k <= n; k++) {
(gdb) <enter> 
21    seriesValue += xpow / ComputeFactorial(k) ;
(gdb) s
ComputeFactorial (number=0) at broken.cpp:7
7  int fact=0;


Note: Step lets you get a closer look at each function and line, while next skips over whole functions to the next one.


Here we use n and s instead of next and step, respectively. If the command is simply a repeat of the previous command, you can just hit return, which will execute the last command. Finally, we step (with s) into ComputeFactorial(). (If we'd used next, it would have stepped over ComputeFactorial.)


9. Where are we?


If you want to know where you are in the program's execution (and how, to some extent, you got there), you can view the contents of the stack using the backtrace command as follows:
     (gdb) bt
     #0  ComputeFactorial (number=0) at broken.cpp:7
     #1  0x08048907 in ComputeSeriesValue (x=3, n=2) at broken.cpp:21
     #2  0x08048a31 in main () at broken.cpp:43


Note: Backtrace lets you see where you have been and what you have done, in the case you get lost or confused it is very useful.


10. Watching changes We can step through the program (using the next command) and examine the values using the print command.


Once again, follow these commands carefully in order to stay on track.
     (gdb) next
     9  for (int j = 0; j <= number; j++) {
     (gdb) n
     10    fact = fact * j;
     (gdb) n
     9  for (int j = 0; j <= number; j++) {
     (gdb) print fact
     $2 = 0
     (gdb) n
     13  return fact;
     (gdb) quit


Try to find the error.
HINT: Look inside the “print fact” command


The print command (abbreviated p) reveals that the value of fact never changes. Note that the function is returning a value of 0 for the function call ComputeFactorial(number=0). This is an ERROR! The answer will always equal zero.

By taking a closer look at the values printed above, we realize that we are computing fact=fact * j where fact has been initialized to 0, (0 = 0 * j); fact should have been initialized to 1. We quit GDB with the quit command. Next we need to change the following line:

(gdb) quit
int fact = 1;
HINT: It is near the top of the program’s code.

Recompile the code and run it, you will get the expected output.