4. Source Code memory
You can use the info line command to view the address of the source code in the memory. Info line can be followed by "row number", "function name", "File Name: line number", and "File Name: function name ", this command prints out the memory address of the specified source code at runtime, for example:
(GDB) info line TST. C: func
Line 5 of "TST. c" starts at address 0x8048456 <func + 6> and ends at 0x804845d <func + 13>.
There is also a command (disassemble) that you can view the machine code of the current execution of the source program. This command will dump the commands in the current memory. The following example shows the assembly code of the function func.
(GDB) disassemble func
Dump of worker er code for function FUNC:
0x8048450 <func>: Push % EBP
0x8048451 <func + 1>: mov % ESP, % EBP
0x8048453 <func + 3>: Sub $0x18, % ESP
0x8048456 <func + 6>: movl $0x0, 0 xfffffffc (% EBP)
0x804845d <func + 13>: movl $0x1, 0xfffffff8 (% EBP)
0x8048464 <func + 20>: mov 0xfffffff8 (% EBP), % eax
0x8048467 <func + 23>: CMP 0x8 (% EBP), % eax
0x804846a <func + 26>: jle 0x8048470 <func + 32>
0x8048480 <func + 28>: JMP 0 <func + 48>
0x804846e <func + 30>: mov % ESI, % ESI
0x8048470 <func + 32>: mov 0xfffffff8 (% EBP), % eax
0x8048473 <func + 35>: Add % eax, 0 xfffffffc (% EBP)
0x8048476 <func + 38>: incl 0xfffffff8 (% EBP)
0x8048479 <func + 41>: JMP 0x8048464 <func + 20>
0x804847b <func + 43>: NOP
0x804847c <func + 44>: Lea 0x0 (% ESI, 1), % ESI
0x8048480 <func + 48>: mov 0 xfffffffc (% EBP), % edX
0x8048483 <func + 51>: mov % edX, % eax
0x8048485 <func + 53>: JMP 0x8048487 <func + 55>
0x8048487 <func + 55>: mov % EBP, % ESP
0x8048489 <func + 57>: Pop % EBP
0x804848a <func + 58>: Ret
End of worker er dump.
View runtime data
-------
When you debug a program, when the program is stopped, you can use the print command (abbreviated as P) or the synonymous Command inspect to view the running data of the current program. The format of the print command is:
Print <expr>
Print/<F> <expr>
<Expr> is an expression, which is the language expression of the program you debug (GDB can debug multiple programming languages), <F> is the output format, for example, if you want to output the expression in hexadecimal format, it is/X.
I. Expressions
Like many gdb commands, print can accept an expression. GDB calculates this expression based on the data of the current program running. Since it is an expression, it can be the const constants, variables, and functions in the current program running. Unfortunately, GDB cannot use the macros you define in the program.
The expression syntax should be the syntax of the language currently being debugged. Since C/C ++ is a popular language, the examples in this article are about C/C ++. (I will introduce the chapters on debugging other languages using GDB later)
In expressions, there are several operators supported by GDB that can be used in any language.
@
Is an array-related operator, which will be described in more detail later.
::
Specifies a variable in a file or function.
{<Type >}< ADDR>
Indicates an object of Type pointing to the memory address <ADDR>.
Ii. program variables
In GDB, you can view the values of the following three variables at any time:
1. Global variables (visible to all files)
2. Static global variables (visible to the current file)
3. Local variables (visible to the current scope)
If your local variables conflict with global variables (that is, duplicate names), the local variables usually hide the global variables, that is, if a global variable and a local variable in a function have the same name, if the current stop point is in the function, the value of the variable displayed with print will be the value of the local variable in the function. If you want to view the global variable value, you can use the ":" OPERATOR:
File: Variable
Function: Variable
You can specify the variable you want to view in this form, which file or function is used. For example, to view the value of global variable X in file f2.c:
GDB) P 'f2. C': x
Of course, the ":" operator will conflict with the c ++ operator. GDB can automatically identify whether the ":" operator is a C ++ operator, so you don't have to worry about exceptions when debugging C ++ programs.
In addition, if optimization options are enabled during program compilation, some variables may be inaccessible when you debug the optimized program using GDB, or a value error code. This is normal, because the optimization program will delete and modify your program, sort out the statement order of your program, and remove some meaningless variables. Therefore, when you debug such a program in GDB, the running commands are different from the ones you write, and the unexpected results are displayed. To deal with this situation, you need to disable compilation optimization during program compilation. Generally, almost all compilers support Compilation optimization. For example, the gnu c/C ++ compiler GCC can be used to solve this problem. For compiler parameters, see the instructions for use of the compiler.
3. Array
Sometimes you need to view the value of a continuous memory space. For example, the size of an array or dynamically allocated data. You can use the "@" operator of GDB. The left side of "@" is the value of the first memory address, and the right side of "@" is the length of the memory you want to view. For example, your program has the following statement:
Int * array = (int *) malloc (LEN * sizeof (INT ));
Therefore, during GDB debugging, you can use the following command to display the value of this dynamic array:
P * array @ Len
The left side of @ is the value of the first address of the array, that is, the content pointed to by the variable array, and the right side is the length of the data. It is saved in the variable Len and the output result is, it looks like this:
(GDB) p * array @ Len
$1 = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40}
If it is a static array, you can directly use the print array name to display all the data in the array.
Iv. Output Format
Generally, GDB outputs the value of a variable based on the type of the variable. However, you can also customize the output format of GDB. For example, you want to output a hexadecimal integer or a binary value to view the bitwise of the integer variable. To do this, you can use the gdb data display format:
X displays variables in hexadecimal format.
D. Display variables in decimal format.
U displays unsigned integers in hexadecimal format.
O display variables in octal format.
T display variables in binary format.
A displays variables in hexadecimal format.
C. Display variables in character format.
F. Display variables in floating point format.
(GDB) p I
$21 = 101
(GDB) P/A I
$22 = 0x65
(GDB) P/C I
$23 = 101 'E'
(GDB) P/F I
$24 = 1.20.31145e-43
(GDB) P/x I
$25 = 0x65
(GDB) P/T I
$26 = 1100101
5. view memory
You can use the EXAMINE command (abbreviated as X) to view the value in the memory address. The syntax of the X command is as follows:
X/<n/f/u> <ADDR>
N, f, and u are optional parameters.
N is a positive integer that shows the memory length, that is, the content of several addresses is displayed from the current address to the back.
F indicates the display format. See the preceding figure. If the address refers to a string, the format can be S. If location 10 is the instruction address, the format can be I.
U indicates the number of bytes requested from the current address. If not specified, GDB defaults to four bytes. The U parameter can be replaced by the following characters. B represents a single byte, H represents a double byte, W represents a four byte, and G represents an octal node. When we specify the byte length, GDB reads and writes the specified byte starting from the memory address specified by the memory and takes it as a value.
<ADDR> indicates a memory address.
The n/f/U parameters can be used together. For example:
Command: X/3uh 0x54320 indicates that the content is read from the memory address 0x54320, h indicates that the two bytes are used as a unit, and 3 indicates three units, U indicates to display in hexadecimal format.
6. Automatic Display
You can set variables that are automatically displayed when the program stops or when you track them in a single step. The relevant GDB command is display.
Display <expr>
Display/<FMT> <expr>
Display/<FMT> <ADDR>
Expr is an expression. FMT indicates the display format. ADDR indicates the memory address. After you set one or more expressions using display, as long as your program is stopped, GDB automatically displays the values of these expressions.
Formats I and S are also supported by display. A very useful command is:
Display/I $ PC
$ PC is the environment variable of GDB, indicating the instruction address./I indicates that the output format is machine instruction code, that is, assembly. When the program is stopped, the source code corresponds to the machine script code. This is a very interesting function.
The following are some display-related gdb commands:
Undisplay <dnums...>
Delete display <dnums...>
Delete automatic display. dnums indicates the automatically displayed number. If you want to delete multiple numbers at the same time, they can be separated by spaces. If you want to delete numbers within a range, you can use a minus sign (for example, 2-5)
Disable display <dnums...>
Enable display <dnums...>
Disable and enalbe do not delete automatically displayed settings, but only make them invalid and restored.
Info display
View the automatic display information set for display. GDB generates a table and reports to you how many automatic display settings are set in debugging, including the number, expression, and enable.
7. Set display options
There are many display options in GDB. Here I will only list most of the commonly used options.
Set print address
Set print address on
Open the address output. When the program displays the function information, GDB displays the function parameter address. The system is enabled by default, such:
(GDB) f
#0 set_quotes (SCSI = 0x34c78 "<", RQ = 0x34c88 "> ")
At input. C: 530
530 if (lquote! = Def_lquote)
Set print address off
Disable function parameter address display, for example:
(GDB) set print ADDR off
(GDB) f
#0 set_quotes (SCSI = "<", RQ = ">") at input. C: 530
530 if (lquote! = Def_lquote)
Show print address
Check whether the current address display option is enabled.
Set print Array
Set print array on
Open the array display. When the array is displayed, each element occupies one row. If it is not opened, each element is separated by a comma. This option is disabled by default. The two related commands are as follows.
Set print array off
Show print Array
Set print elements <number-of-elements>
This option mainly sets the array. If your array is too large, you can specify a <number-of-elements> to specify the maximum length of the data display, when this length is reached, GDB will no longer display it down. If it is set to 0, it indicates no restriction.
Show print Elements
View the options of print elements.
Set print null-Stop <on/off>
If this option is enabled, when the string is displayed, the end character is displayed. This option is off by default.
Set print pretty on
If you enable the printf pretty option, it looks pretty when GDB displays the struct. For example:
$1 = {
Next = 0x0,
Flags = {
Sweet = 1,
Sour = 1
},
Meat = 0x54 "pork"
}
Set print pretty off
Disable the printf pretty option. GDB displays the struct as follows:
$1 = {next = 0x0, flags = {sweet = 1, sour = 1}, meat = 0x54 "pork "}
Show print pretty
View how GDB displays struct.
Set print sevenbit-strings <ON/OFF>
Set whether to display characters in the/NNN format. If yes, the string or character data is displayed in the/NNN format, for example, "/065 ".
Show print sevenbit-strings
Check whether the character display switch is enabled.
Set print Union <on/off>
Sets whether to explicitly display the consortium data in the struct. For example, the following data structure is available:
Typedef Enum {tree, bug} species;
Typedef Enum {big_tree, Acorn, seedling} tree_forms;
Typedef Enum {Caterpillar, cocoon, butterfly}
Bug_forms;
Struct thing {
Species it;
Union {
Tree_forms tree;
Bug_forms bug;
} Form;
};
Struct thing Foo = {tree, {acorn }};
When this switch is enabled, the following information is displayed after the P Foo command is executed:
$1 = {It = tree, form = {tree = Acorn, bug = cocoon }}
When the P Foo command is executed, the following information is displayed:
$1 = {It = tree, form = {...}}
Show print Union
View the display mode of the consortium data
Set Print Object <On/Off>
In C ++, if an object pointer points to its derived class, if this option is enabled, GDB will automatically display the output according to the rules of the virtual method call. If this option is disabled, GDB does not care about the virtual function table. This option is off by default.
Show Print Object
View the settings of object options.
Set print static-members <ON/OFF>
This option indicates whether static data members are displayed when the content of a C ++ object is displayed. The default value is on.
Show print static-members
View the static data member option settings.
Set print vtbl <On/Off>
When this option is enabled, GDB will display the virtual function table in a more regular format. It is disabled by default.
Show print vtbl
View the options of the virtual function display format.
VIII. History
When you use GDB print to view the data when the program runs, each print will be recorded by GDB. GDB will compile the numbers for each print command in the form of $1, $2, $3. Therefore, you can use this number to access previous expressions, such as $1. The benefit of this function is that if you have previously entered a long expression and want to view the value of this expression, you can use the history to access it, saves Repeated input.
IX. GDB Environment Variables
You can define your own variables in the debugging environment of GDB to save running data in some debugging programs. It is easy to define a GDB variable. Use the SET command of GDB. The environment variable of GDB is the same as that of UNIX, and starts with $. For example:
Set $ Foo = * object_ptr
When using environment variables, GDB will create this variable when you use it for the first time. In future use, it will directly swap its values. The environment variable has no type. You can define any type for the environment variable. Including struct and array.
Show convenience
This command is used to view all the environment variables currently set.
This is a powerful function. The interaction between environment variables and program variables makes program debugging more flexible and convenient. For example:
Set $ I = 0
Print bar [$ I ++]-> Contents
Therefore, you do not need to enter the command in print bar [0]-> contents, print bar [1]-> contents. After you enter such a command, you only need to press enter to repeat the previous statement and the environment variables will be automatically accumulated to complete the output-by-one function.
10. View registers
To view the register value, run the following command:
Info registers
View the register information. (Except floating-point registers)
Info all-registers
View All registers. (Including floating-point registers)
Info registers <regname...>
View the status of the specified register.
The register contains the data when the program is running, such as the instruction address (IP) that the program is currently running, and the current stack address (SP) of the program. You can also use the print command to access the register. You only need to add a $ symbol before the register name. For example, p $ EIP.
Change Program Execution
-------
Once the program to be debugged is mounted using GDB, after the program runs, you can dynamically change the running line or variable value of the program to be debugged in GDB based on your own debugging ideas, this powerful function allows you to better debug your program. For example, you can go through all the branches of the program at one run of the program.
1. Modify the variable value
It is easy to modify the variable value when the debugged program runs in GDB. You can use the print command of GDB to complete the modification. For example:
(GDB) print x = 4
The expression x = 4 is the C/C ++ syntax, meaning to change the value of variable X to 4. If your current debugging language is Pascal, then you can use Pascal's Syntax: X: = 4.
In some cases, your variables may conflict with the parameters in GDB, for example:
(GDB) whatis width
Type = double
(GDB) P width
$4 = 13
(GDB) Set width = 47
Invalid Syntax in expression.
Because Set width is the gdb command, the "invalid syntax in expression" setting error occurs. At this time, you can use the set var command to tell GDB, width is not your GDB parameter, but the variable name of the program, such:
(GDB) set var width = 47
In addition, GDB does not report such errors, so it is recommended that you use the gdb command in set var format when changing the value of program variables.
Ii. Redirect execution
In general, the program to be debugged is executed in sequence according to the running sequence of the program code. GDB provides the unordered execution function, that is, GDB can modify the execution sequence of the program and allow the program to jump freely. This function can be completed by the jump command of GDB:
Jump <linespec>
Specifies the running point of the next statement. <Linespce> it can be the row number of the file, the format of file: line, or the offset format of + num. Table-based where the next running statement starts.
Jump <address>
The <address> here is the memory address of the code line.
Note that the jump command does not change the content in the current program stack. Therefore, when you jump from one function to another, an error occurs when the function returns a result after running the function. The result may be very strange, or even the program core dump is generated. So it is best to jump in the same function.
Anyone familiar with Assembly knows that when the program is running, there is a register used to save the memory address of the current Code. Therefore, the jump command changes the value in this register. Therefore, you can use "set $ PC" to change the jump execution address. For example:
Set $ Pc = 0x485
3. Generate semaphores
Use the singal command to generate a semaphore for the program to be debugged. For example, CTRL + C. This is very convenient for program debugging. You can set a breakpoint anywhere in the program running, and generate a semaphore using GDB at the breakpoint, this accurate generation of signals somewhere is very advantageous for program debugging.
Syntax: Signal <singal>. UNIX system semaphores usually start from 1 to 15. Therefore, the value of <singal> is also in this range.
The single command is different from the Shell kill command. When the system's kill command sends a signal to the program to be debugged, It is intercepted by GDB, the single command sends a signal directly to the program to be debugged.
4. force function return
If your debugging breakpoint is in a function and other statements are not executed. You can use the return command to force the function to ignore unexecuted statements and return them.
Return
Return <expression>
Use the return command to cancel the execution of the current function and return immediately. If <expression> is specified, the value of this expression is recognized as the return value of the function.
5. Force call a function
Call <expr>
The expression can be a function to forcibly call the function. And display the return value of the function. If the return value of the function is void, it is not displayed.
Another similar command can also complete this function-print, which can be followed by an expression, so you can also use it to call the function. The difference between print and call is that if the function returns void, call is not displayed, print is the return value of the function, and the value is stored in historical data.
Use GDB in different languages
----------
GDB supports the following languages: C, C ++, Fortran, Pascal, Java, chill, assembly, and Modula-2. Generally, GDB determines the debugging language based on the program you are debugging. For example, if the file name suffix is ". c", GDB considers it a C program. If the file name is suffixed with ". C,. CC,. CP,. cpp,. cxx,. c ++", GDB considers it a C ++ program. While the suffix is ". F,. F", GDB will think of it as a FORTRAN program, and if it is ". S,. s", it will be considered as an assembly language.
That is to say, GDB sets its own language environment based on the language of the program you are debugging, and changes the gdb command with the change of the language environment. For example, when some gdb commands require expressions or variables, the syntax of these expressions or variables is completely changed according to the current language environment. For example, in C/C ++, the pointer syntax is * P, while in Modula-2 it is P ^. In addition, if your current program is compiled by several different languages, GDB can automatically switch the language environment according to different languages during the debugging process. This kind of functionality changed along with the language environment is really considerate for developers.
The following are some commands related to the gdb language environment:
Show Language
View the current language environment. If GDB cannot identify the programming language you are debugging, C is considered the default environment.
Info Frame
View the language of the current function.
Info Source
View the program language of the current file.
If GDB does not detect the current program language, you can also manually set the current program language. Use the set language command.
After the set language command, you can view the supported language types of GDB:
(GDB) set language
The currently understood settings are:
Local or auto automatic setting based on source file
C use the C Language
C ++ use the C ++ Language
ASM use the ASM Language
Chill use the chill Language
FORTRAN use the Fortran language
Java use the Java language
Modula-2 use the Modula-2 Language
Pascal use the PASCAL Language
Scheme use the scheme Language
You can set the current language environment by keeping up with the listed language name after set language.
Postscript
--
GDB is a powerful command line debugging tool. We all know that the power of a command line is that it can form an execution sequence and form a script. The software in UNIX is full of command line, which provides great convenience for program development. The advantage of command line software is that it can be easily integrated together, you can use several simple commands of existing tools to create a very powerful function.