One. GDB Common commands:
Command |
Description |
BackTrace (or BT) |
View function calls and parameters at all levels |
Finish |
Run continuously until the current function returns, and then stop waiting for the command |
FRAME (or F) Framing number |
Select Stack Frame |
info (or i) locals |
View the value of the current stack frame local variable |
List (or L) |
List the source code, followed by the last position, column 10 row at a time |
List line number |
List source code starting from the first few lines |
List function name |
List the source code for a function |
Next (or N) |
Executes the next line of statements |
Print (or P) |
Prints the value of an expression, through which the value of the variable can be modified or the function is called |
Quit (or Q) |
Exiting the gdb debugging environment |
Set Var |
Modifying the value of a variable |
Start |
Start executing the program, stop main waiting for the command in front of the first line of the function statement |
Step (or S) |
Executes the next line of statements and enters into the function if there is a function call |
Two. GDB Learning Small Example:
#include <stdio.h>int add_range (int low, int. high) {Int. I, sum;for (i = low; I <= high; i++) sum = sum + i;return s Um;} int main (void) {int result[100];result[0] = Add_range (1, ten), result[1] = Add_range (1,);p rintf ("Result[0]=%d\nresult [1]=%d\n ", result[0], result[1]); return 0;}
add_range
function from low
add 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]=55result[1]=5105
The first result is correct [20], the second result is obviously not correct, in primary 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 should not suspect the code and should suspect the data, because the first and second run is the same code, if the code is wrong, then why the first result can be correct? However, the data associated with the first and second runs can be different, and incorrect data can lead to incorrect results. 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.
To add an option at compile time -g
, the resulting executable file can be gdb
debugged at source level:
$ gcc-g main.c-o main$ gdb maingnu gdb 6.8-debiancopyright (c) free software Foundation, inc.license gplv3+: GNU GP L version 3 or later
-g
The function of the option is to include the source code information in the executable file, such as the first line of the machine instruction in the executable file corresponding to the source code, but not the entire source file embedded in the executable file, so you must ensure that the gdb
source file can be found during debugging. gdb
provides a shell-like command-line environment, with a (gdb)
prompt at which you can enter a help
category to view commands:
(GDB) Helplist of classes of commands:aliases--aliases of other commandsbreakpoints--Making program stop at certain PO Intsdata--examining datafiles--Specifying and examining filesinternals--maintenance commandsobscure--Obscure Featu Resrunning--Running The Programstack--examining the Stackstatus--Status inquiriessupport--Support FACILITIESTRACEP Oints--tracing of program execution without stopping the programuser-defined--user-defined commandstype ' help ' Followe D by a class name for a list of commands in that 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 further see what commands are in a category, such as files
what commands are available under the View Category:
Try the trial list
command now to list the source code starting with the first line:
(GDB) List 11#include <stdio.h>23int add_range (int low, int.) 4{5int I, sum;6for (i = low; I <= high; i++) 7sum = sum + I;8return sum;9}10
Column only 10 rows at a time, if you want to start from line 11th, you can enter the source code
(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) 11int main (void) 12{13int result[100];14result[0] = Add_range (1, ten); 15result[1] = Add_range (1, 100); 16printf ("result[0]=%d\nresult[1]=%d\n", Result[0], result[1]); 17return 0;18
gdb
Many commonly used commands have shorthand forms, such as list
commands can be written l
, to list a function of the source code can also use the function name to do parameters:
(GDB) L add_range1#include <stdio.h>23int add_range (int low, int.) 4{5int I, sum;6for (i = low; I <= high; i++ ) 7sum = sum + I;8return sum;9}10
Now exit gdb
the environment:
(GDB) quit
We do an experiment, renaming the source code or moving it elsewhere to gdb
debug, so that the source code is not listed:
$ MV main.c mian.c$ gdb main ... (GDB) L5main.c:no such file or directory.in main.c
The gcc
visible -g
option is not to embed the source code in 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 a start
command first:
$ gdb Main ... (GDB) Startbreakpoint 1 at 0x80483ad:file main.c, line 14.Starting program:/home/akaedu/main Main () at Main.c:1414resul T[0] = Add_range (1, ten);(gdb)
gdb
Stop at the main
first statement after the variable definition in the function wait for us to send the command, the gdb
statement listed is the next statement that will be executed. We can use next
the command (shorthand n
) to control these statements to execute in one line:
(GDB) n15result[1] = Add_range (1, +);(gdb) (direct carriage return) 16printf ("result[0]=%d\nresult[1]=%d\n", Result[0], result[1]);( GDB) (direct carriage return) Result[0]=55result[1]=510517return 0;
The n
command executes two rows of assignment statements and one line of print statements in turn, the result is immediately typed when the print statement is executed, and then return
waits for us to send a command before stopping at the 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 (shorthand s
) drilling add_range
function to track execution:
(GDB) StartThe program being debugged have been started already. Start it from the beginning? (Y or N) ybreakpoint 2 at 0x80483ad:file main.c, line 14.Starting program:/home/akaedu/main Main () at Main.c:1414result [0] = Add_range (1, ten);(gdb) Sadd_range (low=1, high=10) at main.c:66for (i = low; I <= high; i++)
This time stops at the add_range
first statement after the variable definition in the function. There are several ways to view the state in a function, and the backtrace
Command (abbreviated 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 0x080483c1 in Main () at main.c:14
It can be seen that the current add_range
function is called by a main
function, and main
the arguments passed in are low=1, high=10
. The stack frame number of the main
function is 1, and add_range
the stack frame number is 0. You can now use info
the command (abbreviated i
) to view add_range
the values of the function's local variables:
(gdb) I localsi = 0sum = 0
If you want to see main
the value of a function's current local variable, you can do so by frame
selecting the 1th stack frame with the command (abbreviated f
) and then looking at the local variables:
(GDB) F 1#1 0x080483c1 in Main () at main.c:1414result[0] = Add_range (1, ten);(gdb) I locals result = {0, 0, 0, 0, 0, 0, 134513196, 225011984, -1208685768, -1081160480, ... -1208623680}
Notice that result
there are many elements in the array that have disorganized values, and we know that uninitialized local variables have indeterminate values. So far everything is fine. Use s
or n
go down a few steps, then use print
the command (abbreviated p
) to print out sum
the value of the variable:
(gdb) s7sum = sum + i; (gdb) (direct carriage return) 6for (i = low, I <= high; i++) (GDB) (direct carriage return) 7sum = sum + i; (gdb) (direct carriage return) 6for (i = low; I <= High; i++) (GDB) p sum$1 = 3
The first cycle i
is 1, the second cycle i
is 2, plus it's 3, yes. The $1
representation here gdb
holds these intermediate results, and the number behind the $ will automatically grow, in order to $1
$2
replace the corresponding value with,,, and $3
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 you return from the current function:
(gdb) Finishrun till exit from #0 add_range (low=1, high=10) at MAIN.C:60X080483C1 in Main () at Main.c:1414result[0] = Add_range (1, 10); Value returned is $ = 55
The return value is 55, you are currently preparing to perform an assignment, s
assign a value with a command, and then view the result
array:
(GDB) s15result[1] = Add_range (1, +);(gdb) P result$3 = {55, 0, 0, 0, 0, 0, 134513196, 225011984,-1208685768, 10811604 The ... -1208623680}
The first value 55 is indeed assigned to the result
No. 0 element of the array. The following s
command goes into add_range
the second call, which is followed by the first view of the parameters and local variables:
(GDB) Sadd_range (low=1, high=100) at main.c:66for (i = low; I <= high; i++) (GDB) bt#0 add_range (low=1, high=100) At Main.c:6#1 0x080483db in Main () at main.c:15 (gdb) I locals i = 11sum = 55
Because of the local variables i
and sum
not initialized, so with an indeterminate value, and because two calls are next to each other, i
and sum
just take the value of the last call, the original example 3.7 "Verify the allocation and release of local variable storage space" is the same reason, But the example I'm trying to do is try to get the local variable to have the sum
initial value of 0 on the first call. i
the initial value is not 0 does not matter, in the for
loop will be assigned to a value of 0, but sum
if the initial value is not 0, the cumulative result will be wrong. OK, we have found the wrong reason, we can exit to gdb
modify the source code. If we do not want to waste this commissioning opportunity, we can gdb
sum
change the initial value to 0 to continue running, and see if there are any other bugs after this change:
(GDB) Set var sum=0 (gdb) Finishrun till exit from #0 add_range (low=1, high=100) at main.c:60x080483db in Main () at MAIN.C:1515RESULT[1] = add_range (1, 100); Value returned is $4 = 5050 (gdb) n16printf ("result[0]=%d\nresult[1]=%d\n", Result[0], result[1]);(gdb) (direct carriage return) result[0]= 55result[1]=505017return 0;
So the result is right. Modifying the value of a variable can be used in addition to the command set
print
, because print
the command followed by an expression, and we know that the assignment and function calls are also expressions, so you can also use print
the command to modify the value of a variable or call a function:
(GDB) P result[2]=33$5 = (GDB) p printf ("result[2]=%d\n", result[2]) result[2]=33$6 = 13
Go GDB Debug Basics