GDB introduction

The GNU SYMBOLIC Debugger (GDB) is a powerful debugging tool in Linux. Can be used to debug Ada, C, C ++, ASM, minimal, D, FORTRAN, Objective-C, Go, Java, PASCAL and other languages.

Let’s use debugging GO code as an example to introduce GDB. The source code is as follows:

package main

import "fmt"

func add(a, b int) int {
	sum := 0
	sum = a + b
	return sum
}
func main(a) {
	sum := add(10.20)
	fmt.Println(sum)
}
Copy the code

Building binary applications:

go build -gcflags="-N -l" -o test main.go
Copy the code

Start debugging

gdb ./test
Copy the code

After entering the GDB debugging interface, run the run command to run the program. If the program is already running, we can attach the process ID of the program for debugging:

$ gdb
(gdb) attach 1785
Copy the code

When attaching is executed, GDB first looks for the process’s executable in the current working directory, and if none is found, then searches the path using the source code file. We can also use the file command to load executable files.

Or run the following command to set the process ID:

gdb test 1785 
gdb test --pid 1785
Copy the code

If the running process does not contain debugging information, we can compile a version with debugging information using the same code, and then run debugging using file and attach.

$ gdb
(gdb) file testReading symbols from test... done. (gdb) attach 1785Copy the code

GDB also supports multi-window graphics startup, with one window displaying source information and the other window displaying debugging information:

gdb test -tui
Copy the code

GDB supports Crtl+X+A to enter multi-window GUI during running. GDB supports the following quick operations:

Crtl+X+A // Switch between multi-window and single-window interface Ctrl +X+ 2 // Display two Windows Ctrl +X+ 1 // Display one windowCopy the code

To run the program

Run the program with the run command:

(gdb) run
Copy the code

Specify command line arguments to run:

(gdb) run arg1 arg2
Copy the code

Or set the command line parameters with the set command:

(gdb) set args arg1 arg2
(gdb) run
Copy the code

In addition to the run command, we can also use the start command to run the program. The start command stops before the first statement of the main function.

(gdb) start
Copy the code

Breakpoints set, view, delete, disable

To set breakpoints

In GDB, breakpoints are set using the break command, which can be abbreviated as B.

  • break function

    Set a breakpoint at the exit of the specified function. After setting a breakpoint, the program stops when entering the specified function

  • break linenum

    Sets a breakpoint at the specified line number

  • break +offset/-offset

    Set a breakpoint on the offset line before or after the current line number. Offset is a natural number

  • break filename:linenum

    Set a breakpoint on line LINenum of filename, the source file

  • break filename:function

    Set a breakpoint at the entry of the function function of filename from the source file

  • break *address

    Set a breakpoint at the memory address where the program runs

  • break

    When the break command has no arguments, it stops at the next command.

  • break … if

    . It can be one of the arguments above. Condition means condition, and stops when the condition is true. For example, in the loop environment, you can set break if I =100 to stop the program when I is 100

Check the breakpoint

We can view breakpoints with the info command:

(gdb) info breakpoint # check all breakpoints
(gdb) info breakpoint 3 Check breakpoint 3
Copy the code

Remove breakpoints

A breakpoint is deleted by using the delete command, which can be abbreviated as d:

(gdb) delete 3 Delete breakpoint 3
Copy the code

Enable and disable breakpoints

(gdb) disable 3 Breakpoint 3 is disabled
(gdb) enable 3 Enable breakpoint 3
Copy the code

debugging

Single step

Next is a single step, so it goes through the code line by line, and when it gets to the function, it doesn’t go inside the function, it skips the function, but it executes the function, step over. We could write it as n.

(gdb) next
Copy the code

Step into the

Step is used to step into execution, similar to the next command, but when a function is encountered, it will step into the function, that is, step into. I could just write it as s.

(gdb) step
Copy the code

The step-related command stepi is used to execute one machine instruction at a time. I can write it as si.

Continue to the next breakpoint

The continue command continues the program until the breakpoint is reached again. This can be shortened to c:

(gdb) continue
(gdb) continue 3 # Skip 3 breakpoints
Copy the code

Continue to run to the specified location

The until command helps us to stop at a line, which can be abbreviated as u:

(gdb) until 5
Copy the code

Skip to perform

Skip can skip unwanted functions or file code at step:

(gdb) skip function add   Skip the add function at # step
(gdb) info skip   # Check skip list
Copy the code

Other related commands:

  • Skip delete [num] Deletes the skip
  • Skip enable [num] Enables the skip
  • Skip disable [num] Disables the skip

Note: When the SKIP number is not included, it is set for all SKIps.

Execute to complete the current function

Using the finish command, you can finish the current function and print the stack address, return value, and parameter value when the function returns, that is, step out.

(gdb) finish
Copy the code

View the source code

The list command in GDB is used to display source information. The list command can be abbreviated to L.

  • list

    Display the source code from the first line, and continue by typing list to list the source code that follows

  • list linenum

    Lists the source code near the linenum line

  • list function

    List the code for function

  • list filename:linenum

    List the lines of linenum in filename

  • list filename:function

    List the code for function in filename

  • list +offset/-offset

    Lists the code around the offset line before or after the current line number. Offset is a natural number.

  • list +/-

    Lists the code after or before the current line

  • list linenum1, linenum2

    Lists the code between lines linenum1 and linenum2

Check the information

The info command displays information, which can be abbreviated as I.

  • info files

    Displays the current debug file, including the program entry address, memory segment layout location, and so on

  • info breakpoints

    Displays a list of breakpoints currently set

  • info registers

    Displays the value of the current register, which can be shortened to I r. You can view the specific register information by specifying the register name: I r RSP

  • info all-registers

    Displays the values of all registers. GDB provides four standard registers: PC is the program counter register and SP is the stack pointer. Fp is used to record the pointer of the current stack frame, PS is used to record the register of the processor state, AND GDB can deal with the problem of inconsistent registers in different architectures. For example, for AMD64 architecture, PC corresponds to the RIP register.

    To reference the contents of a register is to use the register name prefix as a variable. For example, characters are used as variables. For example, characters are used as variables. For example, PC is the program counter register value.

  • info args

    Displays the current function parameters

  • info locals

    Displays the current local variable

  • info frame

    View the details of the current stack frame, including RIP information and the file location of the running instruction

  • info variables

    View variable symbols in the program

  • info functions

    View function symbols in a program

  • info functions regexp

    View function symbols in a program by regular matching

  • info goroutines

    Displays a list of goroutines currently executed, with * indicating the currently executed. Note That go Runtime support needs to be loaded.

  • info stack

    Viewing stack Information

  • info proc mappings

    I proc m for short. View the application memory mapping

  • info proc [procid]

    Display Process Information

  • info proc status

    Display process information, including the user ID and group ID. How many threads are in the process; Virtual memory usage; Suspended signals, blocked signals, ignored signals; TTY. System and user time consumed; Stack size; Nice value

  • info display

  • info watchpoints

    Lists all the watch points that are currently set

  • info line [linenum]

    View the code instruction address information of the first LINenum. Without LINenum, the instruction address information of the current position is displayed

  • info source

    Displays the source code language for this source code

  • info sources

    Displays all source file names with debugging information in the program, displaying two lists: one is the symbol information has been read, one is not read

  • info types

    Displays all type symbols in a program

  • info types regexp

    View type symbols in your program through regular matching

Other similar commands are:

  • show args

    View command line parameters

  • show environment [envname]

    View information about environment variables

  • show paths

    View the running path of the program

  • whatis var1

    Display variable var1 type

  • ptype var1

    Displays the variable var1 type, or if the var1 structure type, displays the structure definition information.

View the call stack

Where can be used to view the call stack information:

(gdb) where #0 _rt0_amd64 () at /usr/lib/go/src/runtime/asm_amd64.s:15 #1 0x0000000000000001 in ?? () #2 0x00007fffffffdd2c in ?? () #3 0x0000000000000000 in ?? (a)Copy the code

Set the watch point

Using the watch command, you can set a watch point. The program stops when the variables at the watch point change. We could write it as wa

(gdb) watch sum
Copy the code

Viewing assembly code

We can display the assembly code automatically by turning on disassemble-next-line.

(gdb) set disassemble-next-line on
Copy the code

We can view the assembly code for the specified function:

(gdb) disassemble main.main
Copy the code

Disassemble can be abbreviated to disas. We can also map the source code and assembly code one by one and view

(gdb) disas /m main.main
Copy the code

GDB default display assembly instruction format is AT&T format, we can change to Intel format:

(gdb) set disassembly-flavor intel
Copy the code

Automatically display variable values

The display command supports the function of automatically displaying variable values. When performing debugging operations such as next or step, GDB will automatically display the value information of the variable or address set by display.

Display command format:

display <expr>
display /<fmt> <expr>
display /<fmt> <addr>
Copy the code
  • Expr is an expression
  • FMT indicates the format of the display
  • Addr indicates the memory address

Other related commands:

  • Undisplay [num]: not displayed
  • Delete display [num]: Indicates the deletion
  • Disable display [num]: disables the automatic display
  • Enable display [num] : enables automatic display
  • Info display: Displays the display information

Note: When the display number is not included, it is set for all display.

Displays the assembly instruction to be executed

We can use the display command to view the assembly instruction to be executed when the program stops:

(gdb) display /i $pc
(gdb) display /3i $pc Display 3 commands at once
Copy the code

To cancel the display, run the undisplay command.

Check backtrace information

The backtrace command displays the stack frame information. We could write it as BT.

(gdb) backtrace Display the current function stack frame and local variable information
(gdb) backtrace full Display the stack frame and local variable values of each function
(gdb) backtrace full n # Display n frames and local variables from inside out
(gdb) backtrace full -n # Display n frames and local variables from outside to inside
Copy the code

Toggle stack frame information

The frame command toggles the stack frame information:

(gdb frame n # where n is the number of layers, the innermost function frame is frame 0
Copy the code

Other related commands:

  • Info Frame: Displays the stack frame list

Debugging multithreading

GDB has a set of commands to aid multithreaded debugging:

  • info threads

    Displays all threads of the current tunable type, with an “*” before the thread ID indicating the current thread being debugged.

  • thread threadid

    Switch thread to thread threaDID

  • set scheduler-locking [on|off|step]

    A multithreaded environment, there are multiple threads running, it will affect the result of debugging a thread, this command to set up the debug the operation situation of multiple threads on said only the current thread will continue debugging, do not block any thread off, all threads can perform, in a single step step, Only the current thread will execute.

  • thread apply [threadid] [all] args

    Execute commands on the thread list. For example, thread Apply all BT full allows you to view local variable information for all threads.

Look at runtime variables

The print command can be used to view the value of a variable. The print command can be abbreviated to p. The print command format is as follows:

print [</format>] <expr>
Copy the code

Format Specifies the format to display variables. Optional. Available values are as follows:

  • X displays variables in hexadecimal format
  • D Displays variables in decimal format
  • U Displays an unsigned integer in hexadecimal format
  • O Displays variables in octal format
  • T Displays variables in binary format
  • A Displays variables in hexadecimal format
  • C Displays variables in character format
  • F Displays variables in floating-point format

Expr can be a variable, an expression, or a register:

(gdb) p var1 Print variable var1
(gdb) p &var1 Print the address of variable var1
(gdb) p $rsp Print the RSP register address
(gdb) p $rsp + 8 # print the address information after RSP plus 8
(gdb) p 0xc000068fd0 # Print 0xC000068FD0 to decimal format
(gdb) p /x 824634150864 Print 824634150864 to convert to hexadecimal format
Copy the code

Print also supports viewing contiguous memory. The @ operator is used to view contiguous memory. The left side of the @ operator is the value of the address of the first memory, and the right side of the @ operator wants to view the length of memory.

For example, int arr[] = {2, 4, 6, 8, 10}; , you can run the following command to view the data of the first three arR units:

(gdb) p *arr@3
$2 = {2, 4, 6}
Copy the code

Look at the values in memory

Using the examine command, you can view the values in the memory address, which can be abbreviated as X. The syntax for the examine command is as follows:

examine /<n/f/u>

  • N indicates the length of the display field, that is, the contents of several addresses backward from the current address.

  • F indicates the display format

    • D digital decimal
    • U Unsigned digit unsigned decimal
    • S String string
    • C character char
    • U Unsigned integer unsigned integer
    • T binary
    • O Octal format
    • X Hex format
    • F The format of a floating point number is float
    • I command instruction
    • A address address
  • U represents the number of bytes requested from the current address. The default is 4 bytes

    • B One byte
    • H Two bytes halfword
    • W Four-byte word
    • G Eight-byte giantWord

Example:

(gdb) x/10c 0x4005d4 Print the first 10 characters
(gdb) x/16xb a Print the first A16 bytes in hexadecimal format
(gdb) x/16ub a Print the first 16 bytes of array A in unsigned decimal format
(gdb) x/16tb a Print the first 16 abyte values in base 2
(gdb) x/16xw a Print the first 16 word (4 bytes) values of array A in hexadecimal format
(gdb) x $rsp Print the value of the address at which the RSP register is executed
(gdb) x $rsp + 8 Print the value of RSP plus 8
(gdb) x 0xc000068fd0 Print the value pointed to by memory 0xC000068fd0
Copy the code

Modify a variable or register value

The set command modifies variables and registers:

(gdb) set var var1=123 # set var1 to 123
(gdb) set var $rax= 123Set register value to 123
(gdb) set environment envname1=123 Envname1 = 123
Copy the code

View the help information about the command

The help command enables you to view the help information about the GDB command.

(gdb) help status # View all command examples
(gdb) help x See the help for using the x command
Copy the code

Search source files

The search command allows you to search for content in the current file using regular expressions. Search is equivalent to the forward-search command, which searches forward from the current position. It can be abbreviated as fo. The reverse-search command is the opposite of the forward-search command and can be abbreviated as rev.

(gdb) search func add # Search the add method forward from the current position
(gdb) rev func add Search the add method backwards from the current
Copy the code

data

  • Beej’s Quick Guide to GDB
  • 100 GDB tips