Introduction to GDB
show language can view the current debugging environment language
set language to view all languages supported by GDB
Set language < language > can set up the current debugging environment language.
What is GDB?
GDB, the GNU Project debugger, allows you to see what is going on `inside' another program while it executes – or what another program was doing at the moment it crashed.
GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:
1.Start your program, specifying anything that might affect its behavior.
2.Make your program stop on specified conditions.
3.Examine what has happened, when your program has stopped.
4.Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.
Those programs might be executing on the same machine as GDB (native), on another machine (remote), or on a simulator. GDB can run on most popular UNIX and Microsoft Windows variants, as well as on Mac OS X.
run
- Start the debugged program, abbreviated as r
- If parameters are required for program execution, run parameters can be added directly after run, or set args can be executed before run
Note: stop to pause the program. Use info program to view the program running status, that is, the reason for stopping
attach
Attach to a running process to debug attach < process ID >
During attach, run again to kill the original process and run the program from scratch
You can use the pidof process name to get the process ID
list
-
Check the source code list, abbreviated l
- Directly enter l to display from the first line,
- l line num can display the source code near the line number
- l function can display the source code near the function name
- l filename:linenum , the source code near linenum of the source file filename can be displayed
- l filename:function to display the source code near the function function of the source file filename
- Sets the number of rows listed at one time
Code
1 2 3
(gdb) set listsize 20 (gdb) show listsize Number of source lines gdb will list by default is 20.
- l first,last print the source code between the first and last lines. First can be defaulted to represent the current location
-
search
You can use this command to search for functions, variables, and so on
break and related breakpoint instructions
- break
Sets a breakpoint at the specified line or function, abbreviated as {b- break when there is no parameter, set a breakpoint at the next instruction executed in the selected stack frame.
- Break , function name break point at the entrance of function body
- Break # line number: break the point at the beginning of the specified line in the current source file.
- break -N ; break +N ¢ is the breaking point at the beginning of the ¢ line before or after the current source line. N ¢ is a positive integer.
- break filename:linenum , break the point at the , linenum , line of , filename , in the source file.
- break filename:function , break the point at the entrance of the , function of , filename , in the source file.
- Break address: break the point at the address of the program instruction. Pay attention to adding * in front of the address when using.
- break... if cond... Sets a conditional breakpoint,... Represents one of the above parameters (or no parameters). Cond is a conditional expression. Program execution is suspended only when the value of... Cond is non-zero.
If there are several functions (function overloading) that you need to break the point, GDB will give you a list of all the functions, which you can choose by yourself
- tbreak
Set a temporary breakpoint. The parameter is the same as {break, but it will be automatically deleted after the program stops for the first time - info breakpoints
Print a list of all breakpoints, observation points and capture points that are not deleted, abbreviated as {i b - disable
Disable breakpoints, abbreviated as dis - clear
Clears the breakpoint at the specified line or function - delete
Clear the breakpoint of the specified num, which is the sequence number in info b
Supplement: when the program is running, if there is no breakpoint, you can directly enter crtl+c to stop the program and enter the GDB command line
-
Breakpoint condition management
- condition
Usage:
condition breakNum expr modify the stop condition of the breakpoint to expr,
condition breakNum: clear the stop condition of the breakpoint - ignore
Usage: ignore breakNUm count ignore breakpoint count timesThe above breakNum is the breakpoint number displayed in info b
- condition
-
Thread breakpoint
When your program is multithreaded, you can define whether your breakpoint is on all threads or on a specific thread.
break line thread threadNo
Where line is the number of lines of your source code, threadNo is the thread ID given by GDB in info threads command, and if threadNo is not specified, it is the breaking point of all threads.
Examples are as follows
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | (gdb) b 27 Breakpoint 1 at 0x400777: file main.c, line 27. (gdb) b 28 Breakpoint 2 at 0x400785: file main.c, line 28. (gdb) b 29 Breakpoint 3 at 0x40078f: file main.c, line 29. (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000400777 in main at main.c:27 2 breakpoint keep y 0x0000000000400785 in main at main.c:28 3 breakpoint keep y 0x000000000040078f in main at main.c:29 (gdb) disable 1 (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep n 0x0000000000400777 in main at main.c:27 2 breakpoint keep y 0x0000000000400785 in main at main.c:28 3 breakpoint keep y 0x000000000040078f in main at main.c:29 (gdb) enable 1 (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000400777 in main at main.c:27 2 breakpoint keep y 0x0000000000400785 in main at main.c:28 3 breakpoint keep y 0x000000000040078f in main at main.c:29 (gdb) clear 27 Deleted breakpoint 1 (gdb) info b Num Type Disp Enb Address What 2 breakpoint keep y 0x0000000000400785 in main at main.c:28 3 breakpoint keep y 0x000000000040078f in main at main.c:29 |
catch capture
Capture points can be set to catch some events when the program is running. For example, loading shared libraries (dynamic link libraries) or C + + exceptions. Format snap points as:
catch event
When an event occurs, stop the program. Event can be the following:
- throw an exception thrown by C + +.
- catch an exception caught by C + +.
- Exec() when the system calls exec.
- Fork} when the system calls fork.
- vfork} when the system calls vfork.
- Load or load when loading a shared library (Dynamic Link Library).
- Unload or unload when unloading a shared library (Dynamic Link Library).
tcatch event
Set the snap point only once. When the program stops, the snap point will be deleted automatically.
step, next, finish and continue control instructions
-
step
Single step tracking. If there is a function call, it will enter the function, abbreviated as {s -
next
For single step tracking, if there is a function call, it will not enter the function, which is abbreviated as n
Single step operation adding i parameter can execute assembly code
-
finish
Execute until the selected stack frame returns, abbreviated as {fin (that is, execute to the return of the current function) -
continue
When gdb encounters a breakpoint and stops, it resumes the execution of the program, abbreviated as {c
print, watch, display and related viewing instructions
-
print
print/f, print the value of a variable or expression, abbreviated as {p, where / f is an optional parameter. You can specify the print output format, and use this command to directly assign values to variables or expressionsAvailable if local and global variables conflict, or if you want to print a variable in another file or function
file::variable
function::variable to indicateCode
1 2 3 4
(gdb) p a $9 = 100 (gdb) p a=10 $10 = 10
-
(1) Print array or memory contents
-
p array name. If the variable itself is an array, the contents of the array can be printed
-
p * pointer @ number. If the variable is dynamically applied memory and you want to print the content according to the pointer type, you can use this method
Examples are as follows:
Code
1 2 3 4 5 6
(gdb) p testArray $1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0} (gdb) p pTmp $2 = (int *) 0x602010 (gdb) p *pTmp@10 $3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
-
-
(2) If the string is too long or the array is too large, you can set the number of elements printed by print to display the complete array
set print elements number of elements to set the number of display elements
show print elements to view the number of display elements
Set print null stop < on > < off >, if this option is enabled, the display will stop when the terminator is encountered when displaying the string, and it will be closed by default
show print null-stopCode
1 2 3 4 5
(gdb) p testArray $4 = "global_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_te"... (gdb) set print elements 1000 (gdb) p testArray $5 = "global_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_testglobal_array_t"...
-
(3) When setting the print structure or class, print the members separately to avoid being stacked together and difficult to view
Set print pretty < on > < off >, to turn on / off branch printing
show print pretty to view the current display formCode
1 2 3 4 5 6 7 8 9
(gdb) p testStruct $1 = {para1 = 100, para2 = 200, testArray = "global_array_testglobal_array_testglobal_array_testglobal_array_"} (gdb) set print pretty (gdb) p testStruct $2 = { para1 = 100, para2 = 200, testArray = "global_array_testglobal_array_testglobal_array_testglobal_array_" }
-
(4) When printing arrays, each element occupies a separate line
Set print array < on > < off >, which turns on / off the exclusive row of elements
show print array to view the current display formCode
1 2 3 4 5 6 7 8 9 10 11 12 13 14
(gdb) p testArray $4 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0} (gdb) set print array on (gdb) p testArray $5 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
-
(5) Sets whether to display Union data in a structure when it is displayed
Set print union < on > < off >, which turns on / off the display of Union data
show print union to view the current display form -
(6) View historical data
Every time you use the print command, GDB will number its output: $1, $2, $3, etc
show value print all historical data
show value n prints 10 historical data centered on n
show value + print the next 10 historical data of the last displayed historical data
-
-
watch
-
Set the observation point for the expression (or variable). When the value of the expression (or variable) changes, pause the program execution
-
rwatch expr stops the program when the expression (variable) expr is read
-
Wait expr stops the program when the value of an expression (variable) is read or written.
-
Usage: watch [- l| - location] < expr > whenever the value of an expression changes, the observation point will pause program execution
If - l , or - location is given, it evaluates , expr , and observes the memory it points to. For example, watch *(int *)0x12345678 will observe a 4-byte area at the specified address (assuming that int occupies 4 bytes)
-
-
display
Display / FMT < expr > < addr > print the value of the content in the expr expression or addr address every time the program stops (automatic display)
fmt is a display format and supports i parameter display assembly codeRelated control commands for display:
-
Undisplay < num >, delete the auto display item
-
Enable < num > to enable automatic display of items
-
Disable < num >, disable automatic display items (do not delete)
-
Info display to view the relevant information of display. The parameters of the above three commands are num listed in info display
Examples are as follows
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
(gdb) display a 1: a = 10 (gdb) info display Auto-display expressions now in effect: Num Enb Expression 1: y a (gdb) display b 2: b = 2 (gdb) info display Auto-display expressions now in effect: Num Enb Expression 2: y b 1: y a (gdb) undisplay 1 (gdb) info display Auto-display expressions now in effect: Num Enb Expression 2: y b (gdb) c Continuing. progran is start Breakpoint 5, main () at main.c:29 29 test(); 2: b = 2 (gdb)
-
-
examine
View memory, abbreviated as x, usage: x / NFU < addr >n. f , and u , are optional parameters that specify the memory to display and how to format it. addr , is the expression to start displaying the address of memory.
-
n ¢ number of repetitions (the default is 1), specifying how many units of memory value to display (specified by ¢ u ¢).
-
f is the display format (the initial default value is "x"), which is one of the formats used by "print" ("x", "d", "u", "o", "t", "a", "c", "f", "s") plus "i" (machine instruction).
-
u = unit size, b = single byte, h = double byte, w = four bytes, g = octets.
for example
Code
1 2 3 4 5 6 7 8
(gdb) x &a 0x7fffffffe47c: 0x0000000a (gdb) x/d &a 0x7fffffffe47c: 10 (gdb) x &b 0x7fffffffe478: 2 (gdb) x/4x &b 0x7fffffffe478: 0x00000002 0x0000000a 0x00000000 0x00000000
-
-
info register
View the value of the register, where register can be abbreviated as reg
info register, view registers (except floating-point registers)
Info all register to view all registers (including floating-point registers)
info register regName to view the contents of the specified register regName
<!--hexoPostRenderEscape:<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">(gdb) info reg</span><br><span class="line">rax 0x4006e7 4196071</span><br><span class="line">rbx 0x0 0</span><br><span class="line">rcx 0x400730 4196144</span><br><span class="line">rdx 0x7fffffffe578 140737488348536</span><br><span class="line">rsi 0x7fffffffe568 140737488348520</span><br><span class="line">rdi 0x1 1</span><br><span class="line">rbp 0x7fffffffe480 0x7fffffffe480</span><br><span class="line">rsp 0x7fffffffe480 0x7fffffffe480</span><br><span class="line">r8 0x7ffff7dd5e80 140737351868032</span><br><span class="line">r9 0x0 0</span><br><span class="line">r10 0x7fffffffdfa0 140737488347040</span><br><span class="line">r11 0x7ffff7a2f410 140737348039696</span><br><span class="line">r12 0x4005b0 4195760</span><br><span class="line">r13 0x7fffffffe560 140737488348512</span><br><span class="line">r14 0x0 0</span><br><span class="line">r15 0x0 0</span><br><span class="line">rip 0x4006eb 0x4006eb <main+4></span><br><span class="line">eflags 0x246 [ PF ZF IF ]</span><br><span class="line">cs 0x33 51</span><br><span class="line">ss 0x2b 43</span><br><span class="line">ds 0x0 0</span><br><span class="line">es 0x0 0</span><br><span class="line">fs 0x0 0</span><br><span class="line">gs 0x0 0</span><br></pre></td></tr></table></figure>:hexoPostRenderEscape-->
backtrace
Check the information of the program call stack, abbreviated as bt, add the full parameter, bt full can print out all variable information
- backtrace n ^ n is a positive integer, indicating the stack information of N layers on the top of the print stack
- backtrace -n - n is a negative number, indicating that it prints the stack information of N layers at the bottom of the stack
- frame n # n is a positive integer, indicating the stack level. frame can be abbreviated as f. use this command to switch the stack information you are currently interested in
- up n n is a positive integer. This command indicates moving n layers to the top of the stack
- down n ^ n is a positive integer. This command indicates moving n layers to the bottom of the stack
- The above command will print the information of the stack layer moved to. If you don't want it to type a message. You can use these three commands
- Select frame , corresponds to the , frame , command
- Up silent , n , corresponds to the , up , command
- Down silently , n , corresponds to the , down , command
- info frame this command prints out the details of the current stack
- the address of the frame
- the address of the next frame down (called by this frame)
- the address of the next frame up (caller of this frame)
- the language in which the source code corresponding to this frame is written
- the address of the frame's arguments
- the address of the frame's local variables
- the program counter saved in it (the address of execution in the caller frame) which registers were saved in the frame
- info args print the arguments of the current stack
- Info localsto print all local variables and their values in the current function
- info catch prints the exception handling information in the current function
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | (gdb) bt #0 add (a=1, b=2) at add.cpp:6 #1 0x00000000004007d4 in main () at main.c:32 (gdb) bt full #0 add (a=1, b=2) at add.cpp:6 No locals. #1 0x00000000004007d4 in main () at main.c:32 testStruct = { para1 = 100, para2 = 200, testArray = "global_array_testglobal_array_testglobal_array_testglobal_array_" } strArray = "local_array_test" a = 10 b = 1634890337 |
Breakpoint command
We can use the commands command provided by GDB to set the running command of the stop point. When the running program is stopped, it can execute the specified command, which is very conducive to automatic debugging. It is a powerful support for automatic debugging based on GDB. The format is as follows:
Code
1 2 3 | commands [breakNum] ... command-list ... end |
Write a list of commands for breakpoint number breakNum. When the program is stopped by this breakpoint, gdb will run the commands in the command list in turn.
Note: when setting, first enter commands [breakNum], and then GDB will prompt you to continue to enter the command list, one command at a time
An example is as follows: a graph flow ♪ (^∀^●) ノ:
If you want to clear the command sequence on the breakpoint, simply execute the commands command and directly type end.
Specify source path
Sometimes, the executable compiled with - g only includes the name of the source file without a path name. GDB provides commands that let you specify the path of the source file for GDB to search.
Now, the path of the source file will be included in most execution programs. You can simply use the nm -l command to view it. You can find the path, name and line number of the source file behind each symbol
GDB can debug without source code, but only assembly code
directory dirname ... Use this command to specify the source file path, where directory can be abbreviated as dir
directory to clear all custom source file paths
show directory to view the path of the custom source file
Code
1 2 3 4 5 6 7 8 9 | (gdb) dir /home Source directories searched: /home:$cdir:$cwd (gdb) show dir Source directories searched: /home:$cdir:$cwd (gdb) dir Reinitialize source path to empty? (y or n) y Source directories searched: $cdir:$cwd (gdb) show dir Source directories searched: $cdir:$cwd |
View source code load memory
In fact, this is the address of the source code in memory when the program is executed
info line + <line><func><file:line><file:func>
Use the disassemble command to directly view the assembly code of the source code, which will display the loading address at the same time
Disassembly
Disassemble < func > <'File ':: func > < start, end > < start, + length > command can view the assembly code. The specific parameters are described below
- /m. Print the source code at the same time
- /r. Print hexadecimal machine code at the same time
- func, print the assembly code of the specified function
- 'file'::func, print the assembly code of a function in the specified file. The format must be written as before. Pay attention to single quotation marks
- start,end, print the assembly code between the start and end addresses
- start,+length, print the assembly code from start to start+length
The original text is as follows:
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 | (gdb) help disas Disassemble a specified section of memory. Default is the function surrounding the pc of the selected frame. With a /m modifier, source lines are included (if available).//Print the source code at the same time With a /r modifier, raw instructions in hex are included.//Print hexadecimal machine code at the same time With a single argument, the function surrounding that address is dumped. Two arguments (separated by a comma) are taken as a range of memory to dump, in the form of "start,end", or "start,+length". Note that the address is interpreted as an expression, not as a location like in the "break" command. So, for example, if you want to disassemble function bar in file foo.c you must type "disassemble 'foo.c'::bar" and not "disassemble foo.c:bar". |
Change the execution of the program
In GDB, you can dynamically change the running line of the current debugged program or the value of its variables in GDB according to your own debugging ideas
After learning the stack changes of function calls, bloggers have tried to change the running route by changing the value of registers in GDB. Originally, GDB directly provided this function
See another article for specific attempts GDB debugging change program execution process
-
Change variable value
print a=100, use the print command to directly change the variable value -
Jump execution
jump line, which specifies the run point of the next statement
jump *address, which specifies the running address of the next statementNote that the jump command will not change the contents of the current program stack. Therefore, when you jump from one function to another, an error will inevitably occur when you pop the stack when the function returns after running, so it is best to jump from the same function.
The blogger's article is to change the stack content to achieve the effect of safe call and return. It is still somewhat different from the jump of GDB, hehe 😁 -
Force call function
Call < expr >, force the function expr to be called, and this method can return normallyThe actual measurement shows that it can return normally, and a lot of stack space is pressed during the call, but the returned instruction address is not clearly seen in it. The details need to be studied
-
Force function return
Return < expr >, force to cancel the execution of the current function and return immediately. If < expr > is specified, it will be returned as a return valueNote: this instruction is different from finish. Finish returns after normal execution, while this instruction forcibly cancels execution
GDB graphical
When entering gdb, add the command - tui parameter to enter the graphical interface (Text User Interface)
The effect is as follows. See another blog for specific operations Graphical interface for GDB debugging (TUI)