GDB Tutorial

Source: Internet
Author: User

Last year to study C, see Song Teacher's "Linux C one-stop programming", feel very suitable for their own. Today with GDB, some unfamiliar, and then look at ~

Original address: http://songjinshan.com/akabook/zh/gdb.html

--------------------

In addition to a clear bug in the program need a certain debugging means to analyze the exact wrong. So far, we have only one debug method: According to the error phenomenon when the program executes, then insert printf in the appropriate place in the code, execute the program and analyze the print results, and if the results are the same as expected, you will be able to fix the bug by basically proving the wrong cause of your assumptions. If the results are not the same as expected, further assumptions and analyses are made based on the results.

In this chapter, we introduce a very powerful debugging tool, GDB, can completely control the operation of the program, so that the program is like the toy in your hand, you call it to go, call it to stop, and at any time can view all the internal state of the program, such as the value of each variable, the parameters passed to the function, the currently executing line of After mastering the usage of GDB, the debugging means are richer. But note that even if the debugging means enriched, the basic idea of debugging is still "analysis phenomenon → hypothesis error reason → produce new phenomenon to verify hypothesis" such a cycle, according to how the phenomenon assumes the wrong reason, and how to design a new phenomenon to verify the hypothesis, which requires very rigorous analysis and thinking, If you misuse the analysis process because you have powerful tools in hand, you will often be cured of local bug fixes, causing a bug to disappear but bugs still exist, even making the program more error-correcting. This chapter explains how to use the GDB debugger to summarize some common GDB commands after each instance by using a few examples of errors that beginners can make. 10.1. Stepping and tracking function calls

Look at the following program:

1
 2
 3
 4
 5
 6
 7
 8
9
18
#include <stdio.h>

int add_range (int low, int. high)
{
        int i, sum;
        for (i = low, I <= high; i++)
                sum = sum + i;
        return sum;
}

int main (void)
{
        int result[1000];
        Result[0] = Add_range (1, ten);
        RESULT[1] = Add_range (1, +);
        printf ("result[0]=%d\nresult[1]=%d\n", Result[0], result[1]);
        return 0;
}

The Add_range function from low to high, in the main function first from 1 to 10, save the results, and then from 1 to 100, and then save the results, the final printing of the two results are:

Result[0]=55
result[1]=5105

The first result is correct, the second result is obviously incorrect [1], in elementary school we heard the story of the high, from 1 to 100 should be 5050. A piece of code, the first run the result is right, the second run is not correct, this is a very common kind of error phenomenon, this situation on the one hand to suspect the code, on the other hand, but also to suspect the data: the first and second run is the same code, if the code is wrong, then why the first result can be correct. So it is possible that the second run-time related state and data is wrong and the wrong data is causing the wrong result. Before commissioning, the reader first try to see the code can see the cause of the error, as long as the previous chapters to learn solid should be able to see.

[1] If you compile the environment to run this program and my environment (Ubuntu 12.04 LTS 32-bit x86) is different, perhaps in your machine can not run out of this result, it does not matter, it is important to learn the method described in this chapter. In addition you can try to modify the program, there is always a way to get similar results, the above example deliberately defined a very large array result[1000], modify the size of the array will change the location of the local variable storage space, the results may be different.

To add the-G option at compile time, the resulting executable file can be debugged using GDB for source-level debugging:

$ gcc-g main.c-o main
$ gdb main
GNU gdb (Ubuntu/linaro 7.4-2012.02-0ubuntu2) 7.4-2012.02
Copyright (c) 2012 Free Software Foundation, Inc.
License gplv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> this was free
software:you be fre E To change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "Show copying" and
"show warranty" for details.
This GDB is configured as "I686-linux-gnu".
For bugs reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>
.... Reading symbols From/home/akaedu/main...done.
(GDB)

The function of the-G option is to add the information of the source file in the executable file, then execute the first line of the machine instruction in main of the file main.c, but not embed the whole source file into the executable file, so you must ensure GDB can find the source file main.c when debugging. GDB provides a shell-like command-line environment, the above (GDB) is a prompt, at this prompt input help can see the category of the command:

(GDB) Help
List of classes of commands:

aliases--aliases of other commands
breakpoints--Making program Sto P at certain points
data--examining data
files--Specifying and examining files
Internals--Maintenance Co Mmands
Obscure--obscure features
running--running the program
stack--examining the stack
status--S Tatus inquiries Support-
-support facilities
tracepoints--tracing of program execution without stopping the P  Rogram
user-defined--user-defined commands

Type ' help ' followed by a class name to a list of commands in Class.
Type ' help all ' for the list of all commands.
Type ' help ' followed by command name for full documentation.
Type "Apropos word" to search for commands related to "word".
Command name abbreviations is allowed if unambiguous.

You can also take a closer look at what commands are in a category, such as see which commands are available under the files Category:

(GDB) Help files
specifying and examining files.

List of commands:

add-symbol-file--load symbols from file
add-symbol-file-from-memory--load the symbols out of Memory from a dynamically loaded object file
CD--Set working directory to DIR for debugger and program being Debugg Ed
core-file--use file as core dump for examining memory and registers
directory--Add directory DIR to Beginni Ng of Search path for source files
edit--Edit specified file or function
exec-file--use file as program for GE tting contents of pure memory
file--use file as program to being debugged
forward-search--Search for regular exp Ression (see Regex (3)) from last line listed
generate-core-file--Save a core file with the current state of the Deb Ugged process
List-list specified function or line ...

Now try the list command to list the source code starting with the first line:

(GDB) List 1
1    #include <stdio.h>
2
3    int add_range (int low, int. high)
4    {
5            int i, sum;
6 for            (i = low, I <= high; i++)
7                    sum = sum + i;
8            return sum;
9    }
10

Only 10 rows are listed at a time, and if you want to proceed from line 11th, the source code can be entered again:

(GDB) List

can also be nothing to lose directly hit Enter, GDB provides a very convenient function, at the prompt to directly hit enter to indicate repeating the previous command:

(GDB) (direct carriage return) one   int main (void
)
: {           int result[1000];           result[0] = Add_range (1, ten);           result[1] = Add_range (1, +);           printf ("result[0]=%d\nresult[1]=%d\n", Result[0], result[1]);           0;
(+   }

GDB's many common commands have shorthand form, for example, the list command can be written as L, the source code to list A function can also be used to do the function name parameters:

(GDB) L add_range
1    #include <stdio.h>
2
3    int add_range (int low, int. high)
4    {
5            int i, sum;
6 for            (i = low, I <= high; i++)
7                    sum = sum + i;
8            return sum;
9    }
10

Now exit the GDB environment:

(GDB) quit

We do an experiment, rename the source code or move it elsewhere and debug it with GDB, so that the source code is not listed:

$ mv main.c MIAN.C
$ gdb main
...
(GDB) L
5    main.c:no such file or directory.

The-G option for GCC does not embed the source code into the executable file, and the source file is also required for debugging. Now that the source code is restored, we continue to debug. Start the execution of the program with the start command first:

$ gdb main
...
(GDB) Start
Temporary breakpoint 1 at 0x8048415:file main.c.
Starting program:/home/akaedu/main

Temporary Breakpoint 1, Main () at main.c:14
result[0           ] = Add_range (1, ten);
(GDB)

GDB stops at the first statement after the variable definition in the main function to wait for us to send the command (GDB's last statement before the prompt is always "the next statement to be executed"). We can use the next command (abbreviated as n) to control these statements in one-by-one execution:

(GDB) n           result[1] = Add_range (1, +);
(GDB) (direct carriage return)-           printf ("result[0]=%d\nresult[1]=%d\n", Result[0], result[1]);
(GDB) (direct carriage return)
result[0]=55
result[1]=5105 +           return 0;

The n command executes two rows of assignment statements and one line of print statements, and the result is immediately typed when the print statement is executed, and then waits for us to send a command before the return statement. Although we have complete control over the execution of the program, we still do not see what is wrong, because the error is not in the main function and in the Add_range function, now with the start command again, this time with the Step command (abbreviated as s) drilling into the Add_range function to track execution:

(GDB) Start the program
being debugged have been started already.
Start it from the beginning? (Y or N) y
temporary breakpoint 2 at 0x8048415:file main.c.
Starting program:/home/akaedu/main

Temporary Breakpoint 2, main () at main.c:14
result[0           ] = Add_range (1, (ten);
(GDB) S
add_range (low=1, high=10) at Main.c:6
6 for            (i = low; I <= high; i++)

This time stops at the first statement after the variable definition in the Add_range function. There are several ways to view states in a function, and the BackTrace command (BT) allows you to view the stack frame of a function call:

(GDB) bt #0 add_range (Low=1, high=10) at Main.c:6 #1 0x08048429 in Main () at main.c:14

It is visible that the current Add_range function is called by the main function, and the parameter passed in by Main is Low=1, high=10. The stack frame number of the main function is 1, and the stack frame number of the Add_range is 0. You can now view the value of the Add_range function local variable with the info command (abbreviated as I):

(GDB) I locals
i = 0
sum = 0

If you want to see the value of the current local variable of the main function, you can use the Frame command (f) to select the 1th stack frame and then view the local variables:

(GDB) F 1
#1  0x08048429 in Main () at main.c:14           result[0] = Add_range (1, ten);
(GDB) I locals
result = {0 <repeats 471 times>, 1184572, 0 <repeats one times>,-1207961512,-1073746088, 1 249268, -1073745624, 1142336,
...

Notice that the values of many elements in the result array are disorganized, and we know that uninitialized local variables have indeterminate values, so far everything is fine. Go down a few steps with S or N and print the value of the variable sum using the Print command (p):

(GDB) s
7                    sum = sum + i;
(GDB) (direct carriage return)
6 for            (i = low, I <= high; i++)
(GDB) (direct carriage return)
7                    sum = sum + i;
(GDB) (direct carriage return)
6 for            (i = low, I <= high; i++)
(GDB) p sum $
= 3

The first cycle I is 1, the second cycle I is 2, plus it is 3, yes. Here the $ $ means gdb holds these intermediate results, and the number behind the $ will automatically grow, in order to replace the corresponding value with a number of $, $, $ $, and so on. Since we knew that the result of the first call was correct, and it didn't make sense to go down with it, you can use the finish command to keep the program running until it returns from the current function:

(GDB) Finish
Run till exit from #0  add_range (low=1, high=10) at Main.c:6
0x08048429 in Main () at main.c:14
  14           Result[0] = Add_range (1, ten);
Value returned is $ = 55

The return value is 55, and you are currently preparing to perform an assignment with the n command to view the result array after performing the assignment operation:

(GDB) n           result[1] = Add_range (1, +);
(GDB) p result $
= {0 <repeats 470 times>, 1184572, 0 <repeats one times>,-1207961512,-1073746088, 1 249268, -1073745624, 1142336,
...

The first value 55 is indeed assigned to the No. 0 element of the result array. Following the S command into the second Add_range call, enter after the first view parameters

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

Tags Index: