Chapter 8. GNU Debugger (GDB)

The GNU Debugger, commonly abbreviated as GDB, is a command line tool that can be used to debug programs written in various programming languages. It allows you to inspect memory within the code being debugged, control the execution state of the code, detect the execution of particular sections of code, and much more.

Red Hat Developer Toolset is distributed with GDB 9.2. This version is more recent than the version included in Red Hat Enterprise Linux and the previous release of Red Hat Developer Toolset and provides some enhancements and numerous bug fixes.

8.1. Installing the GNU Debugger

In Red Hat Developer Toolset, the GNU Debugger is provided by the devtoolset-10-gdb package and is automatically installed with devtoolset-10-toolchain as described in Section 1.5, “Installing Red Hat Developer Toolset”.

8.2. Preparing a Program for Debugging

Compiling Programs with Debugging Information

To compile a C program with debugging information that can be read by the GNU Debugger, make sure the gcc compiler is run with the -g option:

$ scl enable devtoolset-10 'gcc -g -o output_file input_file...'

Similarly, to compile a C++ program with debugging information:

$ scl enable devtoolset-10 'g++ -g -o output_file input_file...'

Example 8.1. Compiling a C Program With Debugging Information

Consider a source file named fibonacci.c that has the following contents:

#include <stdio.h>
#include <limits.h>

int main (int argc, char *argv[]) {
  unsigned long int a = 0;
  unsigned long int b = 1;
  unsigned long int sum;

  while (b < LONG_MAX) {
    printf("%ld ", b);
    sum = a + b;
    a = b;
    b = sum;
  }

  return 0;
}

Compile this program on the command line using GCC from Red Hat Developer Toolset with debugging information for the GNU Debugger:

$ scl enable devtoolset-10 'gcc -g -o fibonacci fibonacci.c'

This creates a new binary file called fibonacci in the current working directory.

Installing Debugging Information for Existing Packages

To install debugging information for a package that is already installed on the system:

# debuginfo-install package_name

Note that the yum-utils package must be installed for the debuginfo-install utility to be available on your system.

Example 8.2. Installing Debugging Information for the glibc Package

Install debugging information for the glibc package:

# debuginfo-install glibc
Loaded plugins: product-id, refresh-packagekit, subscription-manager
--> Running transaction check
---> Package glibc-debuginfo.x86_64 0:2.17-105.el7 will be installed
...

8.3. Running the GNU Debugger

To run the GNU Debugger on a program you want to debug:

$ scl enable devtoolset-10 'gdb file_name'

This starts the gdb debugger in interactive mode and displays the default prompt, (gdb). To quit the debugging session and return to the shell prompt, run the following command at any time:

(gdb) quit

Note that you can execute any command using the scl utility, causing it to be run with the Red Hat Developer Toolset binaries used in preference to the Red Hat Enterprise Linux system equivalent. This allows you to run a shell session with Red Hat Developer Toolset gdb as default:

$ scl enable devtoolset-10 'bash'
Note

To verify the version of gdb you are using at any point:

$ which gdb

Red Hat Developer Toolset’s gdb executable path will begin with /opt. Alternatively, you can use the following command to confirm that the version number matches that for Red Hat Developer Toolset gdb:

$ gdb -v

Example 8.3. Running the gdb Utility on the fibonacci Binary File

This example assumes that you have successfully compiled the fibonacci binary file as shown in Example 8.1, “Compiling a C Program With Debugging Information”.

Start debugging fibonacci with gdb:

$ scl enable devtoolset-10 'gdb fibonacci'
GNU gdb (GDB) Red Hat Enterprise Linux 8.2-2.el7
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from fibonacci...done.
(gdb)

8.4. Listing Source Code

To view the source code of the program you are debugging:

(gdb) list

Before you start the execution of the program you are debugging, gdb displays the first ten lines of the source code, and any subsequent use of this command lists another ten lines. Once you start the execution, gdb displays the lines that are surrounding the line on which the execution stops, typically when you set a breakpoint.

You can also display the code that is surrounding a particular line:

(gdb) list file_name:line_number

Similarly, to display the code that is surrounding the beginning of a particular function:

(gdb) list file_name:function_name

Note that you can change the number of lines the list command displays:

(gdb) set listsize number

Example 8.4. Listing the Source Code of the fibonacci Binary File

The fibonacci.c file listed in Example 8.1, “Compiling a C Program With Debugging Information” has exactly 17 lines. Assuming that you have compiled it with debugging information and you want the gdb utility to be capable of listing the entire source code, you can run the following command to change the number of listed lines to 20:

(gdb) set listsize 20

You can now display the entire source code of the file you are debugging by running the list command with no additional arguments:

(gdb) list
1       #include <stdio.h>
2       #include <limits.h>
3
4       int main (int argc, char *argv[]) {
5         unsigned long int a = 0;
6         unsigned long int b = 1;
7         unsigned long int sum;
8
9         while (b < LONG_MAX) {
10          printf("%ld ", b);
11          sum = a + b;
12          a = b;
13          b = sum;
14        }
15
16        return 0;
17      }

8.5. Setting Breakpoints

Setting a New Breakpoint

To set a new breakpoint at a certain line:

(gdb) break file_name:line_number

You can also set a breakpoint on a certain function:

(gdb) break file_name:function_name

Example 8.5. Setting a New Breakpoint

This example assumes that you have compiled the fibonacci.c file listed in Example 8.1, “Compiling a C Program With Debugging Information” with debugging information.

Set a new breakpoint at line 10:

(gdb) break 10
Breakpoint 1 at 0x4004e5: file fibonacci.c, line 10.

Listing Breakpoints

To display a list of currently set breakpoints:

(gdb) info breakpoints

Example 8.6. Listing Breakpoints

This example assumes that you have followed the instructions in Example 8.5, “Setting a New Breakpoint”.

Display the list of currently set breakpoints:

(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004004e5 in main at fibonacci.c:10

Deleting Existing Breakpoints

To delete a breakpoint that is set at a certain line:

(gdb) clear line_number

Similarly, to delete a breakpoint that is set on a certain function:

(gdb) clear function_name

Example 8.7. Deleting an Existing Breakpoint

This example assumes that you have compiled the fibonacci.c file listed in Example 8.1, “Compiling a C Program With Debugging Information” with debugging information.

Set a new breakpoint at line 7:

(gdb) break 7
Breakpoint 2 at 0x4004e3: file fibonacci.c, line 7.

Remove this breakpoint:

(gdb) clear 7
Deleted breakpoint 2

8.6. Starting Execution

To start an execution of the program you are debugging:

(gdb) run

If the program accepts any command line arguments, you can provide them as arguments to the run command:

(gdb) run argument

The execution stops when the first breakpoint (if any) is reached, when an error occurs, or when the program terminates.

Example 8.8. Executing the fibonacci Binary File

This example assumes that you have followed the instructions in Example 8.5, “Setting a New Breakpoint”.

Execute the fibonacci binary file:

(gdb) run
Starting program: /home/john/fibonacci

Breakpoint 1, main (argc=1, argv=0x7fffffffe4d8) at fibonacci.c:10
10          printf("%ld ", b);

8.7. Displaying Current Values

The gdb utility allows you to display the value of almost anything that is relevant to the program, from a variable of any complexity to a valid expression or even a library function. However, the most common task is to display the value of a variable.

To display the current value of a certain variable:

(gdb) print variable_name

Example 8.9. Displaying the Current Values of Variables

This example assumes that you have followed the instructions in Example 8.8, “Executing the fibonacci Binary File” and the execution of the fibonacci binary stopped after reaching the breakpoint at line 10.

Display the current values of variables a and b:

(gdb) print a
$1 = 0
(gdb) print b
$2 = 1

8.8. Continuing Execution

To resume the execution of the program you are debugging after it reached a breakpoint:

(gdb) continue

The execution stops again when another breakpoint is reached. To skip a certain number of breakpoints (typically when you are debugging a loop):

(gdb) continue number

The gdb utility also allows you to stop the execution after executing a single line of code:

(gdb) step

Finally, you can execute a certain number of lines:

(gdb) step number

Example 8.10. Continuing the Execution of the fibonacci Binary File

This example assumes that you have followed the instructions in Example 8.8, “Executing the fibonacci Binary File”, and the execution of the fibonacci binary stopped after reaching the breakpoint at line 10.

Resume the execution:

(gdb) continue
Continuing.

Breakpoint 1, main (argc=1, argv=0x7fffffffe4d8) at fibonacci.c:10
10          printf("%ld ", b);

The execution stops the next time the breakpoint is reached.

Execute the next three lines of code:

(gdb) step 3
13          b = sum;

This allows you to verify the current value of the sum variable before it is assigned to b:

(gdb) print sum
$3 = 2

8.9. Additional Resources

For more information about the GNU Debugger and all its features, see the resources listed below.

Installed Documentation

Installing the devtoolset-10-gdb-doc package provides the following documentation in HTML and PDF formats in the /opt/rh/devtoolset-10/root/usr/share/doc/devtoolset-10-gdb-doc-9.2 directory:

  • The Debugging with GDB book, which is a copy of the upstream material with the same name. The version of this document exactly corresponds to the version of GDB available in Red Hat Developer Toolset.
  • The GDB’s Obsolete Annotations document, which lists the obsolete GDB level 2 annotations.

Online Documentation

See Also