Code Debugging with GDB - part 1: Basic Commands

Abstract

This article describes basic commands in GDB and how to use it.

Start GDB

Start a process without parameters

1
gdb <executable-file>

Start a process with parameters

1
2
gdb -- args <executable-file> <arg1> <argn>
gdb --args ./samples/main ./config.txt

Debug a running process

1
2
3
gdb
attach <process-id>
attach <8888>

Debug the process with command files

Command file is a file containing gdb commands.

1
gdb -x <commmand-file>
1
2
3
4
5
6
7
8
9
gdb -x main.gdb
# Specify the path of the executable file
file ./samples/main
# Set the parameters of the executable file (if any)
set args ./config.txt
# Start the process
start
# Continue execution
c

Debugging Process

View process information

View process ID, executable file path, current directory

1
2
info proc
i proc

View all threads

1
2
info threads
i threads

View the thread where the breakpoint is currently located

1
p $_thread

View stack information

View the stack information of the current thread

1
2
3
4
# Only print the call level of stack information
(gdb) bt
# Print the call level of stack information, and print the value of function parameters and local variables
(gdb) bt full

View the stack information of all threads

1
2
thread apply all bt
thread apply all where

View the stack information of the specified thread

1
2
thread <thread-id-by-gdb>
bt

View/set the search path of the source code

View the source code search path

1
show directories

Add source code search path

1
directory <source-code-path>

Reset the the deault source code search path

1
directory

View source code/assembly

Note: To view the source code, you must include -goption when compiling.

View the source code of the current file

1
list <line-number>

View the source code of the specified file

1
list <file-name>:<line-number>

View the assembly code of the specified function

1
2
3
4
5
# Print assembly code
disas <function-name>

# Print assembly code and corresponding source code
disas /m <function-name>

View/set/Debug breakpoints

Add breakpoints (all threads)

1
b <file-name>:<line-number>

Add breakpoints (specify thread)

1
b <file-name>:<line-number> thread <thread-id-by-gdb>

Add breakpoints to the specified memory address

1
b *<address>

Add conditional breakpoints

1
b <file-name>:<line-number> if <expression>

View all breakpoints

1
i breakpoints

View the specified breakpoint

1
i breakpoints <breakpoint-number>

View breakpoints in the specified range

1
i breakpoints <breakpoint-number>-<breakpoint-number>

Delete breakpoints

1
d
1
2
d breakpoints <breakpoints-number>
d breakpoints <breakpoints-number>:<breakpoints-number>

Debugging

Step/jump

Single step (statement level)

1
next

Single step (instruction level)

1
nexti

Jump into the function (statement level)

1
step

Jump into the function (intruction level)

1
stepi

Jump out function

1
finish

Continue

1
2
continue
c
1
print <variable-name>
1
2
3
4
display <variable-name>
undisplay <variable-name>
# Check the variable are available for automatic printing
i display
1
2
i args
i locals

View/change the value of the register

1
2
3
4
i registers
i registers all
p $rcx
p $rcx=1 # change value

View the value of memory

1
2
3
x/<n><f><u> <address>
x/wx
x/gx

f represents the output format, and the default value is

x (hexadecimal).

i machine instruction, ignore the size of the output unit;

d (signed) decimal;

u (unsigned) decimal;

o octal;

t binary;

a hexadecimal, omitted The first 0;

s a character string, and the default output unit size is b (bytes).

u represents the output unit size

The default value is w (Words, 4 bytes)

b bytes;

h Halfwords, 2 bytes;

g Giant words, 8 bytes.

Note: When the command x is executed, if the specified output unit size is not displayed, the last specified value will be used by default.

Calling C/C++ functions

1
call <function-name>

Debug coredump files

Step 1: Check whether coredump is turned on

1
$ ulimit -c

Note: If the output result is 0, then coredump is not turned on.

Step 2: Turn on coredump

Turn on coredump and don’t limit the size of the core file (only valid for the current session):

1
$ ulimit -c unlimited

Step 3: Debug coredump files

1
$ gdb <executable-file> <coredump-file-path>

**Note: ** <executable-file> is the executable file used when coredump occurs.

Step 4: View stack information

See the view stack information in this article.

Setup GDB log function

  • Turn on/off log output function
1
2
3
4
5
6
7
# Turn on the log output function, and the default log output file name is gdb.txt
(gdb) set logging on
# Turn off the log output function
(gdb) set logging off
# Turn on the log output function and specify the log output file
# (gdb) set logging on gdb_log.txt
(gdb) set logging on <log-file>

Note: After opening the log output function, the output of gdb will be written to the specified log file.

  • Change the file of log output
1
(gdb) set logging file <log-file>
  • Set the way to write log files: overwrite/append write
1
2
3
4
# Set the way to write log files: overwrite
(gdb) set logging overwrite on
# Set the way to write the log file: append write
(gdb) set logging overwrite off

Note: The default mode of gdb is append write.

Note: After setting overwrite or additional write, you need to execute set logging on again to take effect.

Example:

1
2
3
4
file ./main
set logging overwrite on
set logging on test.log
starrt
  • Set whether to redirect gdb output
1
2
3
4
# The output of gdb is only written to the log output file, not to the console
(gdb) set logging redirect on
# The output of gdb will be written to the log output file and the console
(gdb) set logging redirect off
  • View the current log output settings
1
2
3
4
(gdb) show logging 
Currently logging to "debug_navigator.txt".
Logs will be appended to the log file.
Output is being logged and displayed.