The GDB developer's GNU Debugger tutorial, Part 1: Getting started with the debugger | Red Hat Developer (2024)

This article is the first in a series demonstrating how to use the GNU Debugger (GDB) effectively to debug applications in C and C++. If you have limited or no experience using GDB, this series will teach you how to debug your code more efficiently. If you are already a seasoned professional using GDB, perhaps you will discover something you haven't seen before.

In addition to providing developer tips and tricks for many GDB commands, future articles will also cover topics such as debugging optimized code, offline debugging (core files), and server-based sessions (aka gdbserver, used in container debugging).

Why another GDB tutorial?

The majority of GDB tutorials available on the web consist of little more than introductions to the basic list, break, print, and run commands. New GDB users just might as well read (or sing) the official GDB Song!

Instead of simply demonstrating a handful of useful commands, each article in this series will focus on one aspect of using GDB from the perspective of someone who develops GDB. I use GDB daily, and these tips and tricks are the ones that I (and many other advanced GDB users and developers) use to streamline our debugging sessions.

Because this is the first article in the series, allow me to follow the recommendation of the GDB Song and start at the very beginning: How to run GDB.

Compiler options

Let me get the (all-too-often-not-so) obvious out of the way: For the best debugging experience, build applications without optimization and with debugging information. That is trivial advice, but GDB's public IRC channel (#gdb) sees these issues often enough that they warrant mentioning.

TL;DR: Don't debug applications with optimization if you can avoid it. Watch for a future article on optimization.

Optimization can cause GDB to behave in surprising ways if you are not aware of what might be happening "under the covers." I always use the C compiler option -O0 (that's the letter O followed by the number zero) to build executables during the development cycle.

I also always have the toolchain emit debugging information. This is accomplished with the -g option. Specifying the exact debug format is no longer necessary (or desirable); DWARF has been the default debugging information format on GNU/Linux for many years. So ignore advice to use -ggdb or -gdwarf-2.

The one specific option worth adding is -g3, which tells the compiler to include debugging information about the macros (#define FOO ...) used in your application. These macros may then be used in GDB just like any other symbol in your program.

In short, for the best debugging experience, use -g3 -O0 when compiling your code. Some environments (such as those using GNU autotools) set environment variables (CFLAGS and CXXFLAGS) that control the compiler's output. Check these flags to make sure that your invocations of the compiler enable the debugging environment you want.

For much more information about the impact of -g and -O on the debugging experience, see Alexander Oliva's treatise GCC gOlogy: Studying the Impact of Optimizations on Debugging.

Startup scripts

Before we look at actually using GDB, something must be said about how GDB starts up and what script files it executes. Upon startup, GDB will execute the commands contained in a number of system and user script files. The location and order of execution of these files are as follows:

  1. /etc/gdbinit (not on FSF GNU GDB): In many GNU/Linux distributions, including Fedora and Red Hat Enterprise Linux, GDB looks first for the system default initialization file and executes commands contained therein. On Red Hat-based systems, this file executes any script files (including Python scripts) installed in /etc/gdbinit.d.
  2. $HOME/.gdbinit: GDB will then read the user's global initialization script from the home directory, if this file exists.
  3. ./.gdbinit: Finally, GDB will look for a startup script in the current directory. Think of this as an application-specific customization file where you can add per-project user-defined commands, pretty-printers, and other customizations.

All of these startup files contain GDB commands to execute, but they may also include Python scripts as long as they are prefaced with the python command, e.g., python print('Hello from python!').

My .gdbinit is actually quite simple. Its most essential lines enable command history so that GDB remembers a given number of commands that were executed from a previous session. This is analogous to the shell's history mechanism and .bash_history. The entire file is:

set pagination offset history save onset history expansion on

The first line turns off GDB's built-in paging. The next line enables saving the history (to ~/.gdb_history by default), and the final line enables shell-style history expansion with the exclamation point (!) character. This option is normally disabled because the exclamation point is also a logical operator in C.

To prevent GDB from reading initialization files, give it the --nx command-line option.

Getting help in GDB

There are several ways to get help using GDB, including extensive—if dry—documentation explaining every little switch, knob, and feature.

GDB community resources

The community offers help to users in two places:

However, because this article is about using GDB, the easiest way for users to get help with a command is to use GDB's built-in help system, discussed next.

Accessing the help system

Access GDB's built-in help system via the help and apropos commands. Don't know how to use the printf command? Ask GDB:

(gdb) help printfFormatted printing, like the C "printf" function.Usage: printf "format string", ARG1, ARG2, ARG3, ..., ARGNThis supports most C printf format specifications, like %s, %d, etc.(gdb)

help accepts the name of any GDB command or option and outputs usage information for that command or option.

Like all GDB commands, the help command supports tab completion. This is perhaps the most useful way to figure out what types of arguments many commands accept. For instance, entering help show ar and pressing the tab key will prompt you for a completion:

(gdb) help show ararchitecture args arm(gdb) help show ar

GDB leaves you at the command prompt ready to accept further refinement of the input. Adding g to the command, followed by a tab, will complete to help show args:

(gdb) help show argsShow argument list to give program being debugged when it is started.Follow this command with any number of args, to be passed to the program.(gdb)

Don't know the exact name of the command you're looking for? Use the apropos command to search the help system for specific terms. Think of it as grepping the built-in help.

Now that you know how and where to find help, we're ready to move on to starting GDB (finally).

Starting GDB

Unsurprisingly, GDB accepts a large number of command-line options to change its behavior, but the most basic way to start GDB is to pass the application's name to GDB on the command line:

$ gdb myprogramGNU gdb (GDB) Red Hat Enterprise Linux 9.2-2.el8Copyright (C) 2020 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <>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-pc-linux-gnu".Type "show configuration" for configuration details.For bug reporting instructions, please see:<>.Find the GDB manual and other documentation resources online at: <>.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from /home/blog/myprogram...(gdb) 

GDB starts up, prints out some version information (GCC Toolset 10 shown), loads the program and its debug information, and displays copyright and help messages, ending with the command prompt, (gdb). GDB is now ready to accept input.

Avoiding messages: The -q or --quiet option

I've seen GDB's startup message thousands of times, so I suppress (or "quiet") it with the -q option:

$ gdb -q myprogramReading symbols from /home/blog/myprogram...(gdb) 

That's much less to read. If you are really new to GDB, you might find the full startup messaging useful or soothing, but after a while, you'll also alias gdb in your shell to gdb -q. If you do need the suppressed information, use the -v command-line option or the show version command.

Passing arguments: The --args option

Programs often require command-line arguments. GDB offers multiple ways to pass these to your program (or "inferior," in GDB parlance). The two most useful ways are to pass application arguments via the run command or at startup via the --args command-line option. If your application is normally started with myprogram 1 2 3 4, simply preface this with gdb -q --args and GDB will remember how your application should be run:

$ gdb -q --args myprogram 1 2 3 4Reading symbols from /home/blog/myprogram...(gdb) show argsArgument list to give program being debugged when it is started is "1 2 3 4".(gdb) runStarting program: /home/blog/myprogram 1 2 3 4[Inferior 1 (process 1596525) exited normally]$

Attaching to a running process: The --pid option

If an application is already running and gets "stuck," you might want to look inside to find out why. Just give GDB the process ID of your application with --pid:

$ sleep 100000 &[1] 1591979$ gdb -q --pid 1591979Attaching to process 1591979Reading symbols from /usr/bin/sleep...Reading symbols from .gnu_debugdata for /usr/bin/sleep...(No debugging symbols found in .gnu_debugdata for /usr/bin/sleep)Reading symbols from /lib64/ symbols from /usr/lib/debug/usr/lib64/ symbols from /lib64/ symbols from /usr/lib/debug/usr/lib64/ in __GI___clock_nanosleep (requested_time=requested_time@entry=0, remaining=remaining@entry=0x0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:2828 return SYSCALL_CANCEL (nanosleep, requested_time, remaining)(gdb) 

With this option, GDB automatically loads symbols for programs that have build ID information, such as distribution-supplied packages, and interrupts the program so that you can interact with it. Look for more on how and where GDB finds debug information in a future article.

Following up on a failure: The --core option

If your process aborted and dumped core, use the --core option to tell GDB to load the core file. If the core file contains the build ID of the aborted process, GDB automatically loads that binary and its debugging information if it can. Most developers, however, need to pass an executable to GDB with this option:

$ ./abort-meAborted (core dumped)$ gdb -q abort-me --core core.2127239Reading symbols from abort-me...[New LWP 2127239]Core was generated by `./abort-me'.Program terminated with signal SIGABRT, Aborted.#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:5050 return ret;(gdb)

Tip: Can't find a core file? On GNU/Linux systems using systemd, check ulimit -c to see whether the shell is preventing programs from creating core files. If the value is unlimited, use coredumpctl to find the core file. Alternatively, run sysctl -w kernel.core_pattern=core to configure systemd to output core files named core.PID, as I have for the previous example.

Expedited command execution: The --ex, --iex, --x, and --batch options

I often run GDB commands repeatedly from the shell to test for problems or run scripts. These command-line options help facilitate that. Most users will use (multiple) --ex arguments to specify commands to run at startup to recreate a debugging session, e.g., gdb -ex "break some_function if arg1 == nullptr" -ex r myprogram.

  • --ex CMD runs the GDB command CMD after the program (and debug information) is loaded. --iex does the same, but executes CMD before the specified program is loaded.
  • -x FILE executes GDB commands from FILE after the program is loaded and --ex commands execute. I use this option most often if I need a lot of --ex arguments to reproduce a specific debugging session.
  • --batch causes GDB to exit immediately at the first command prompt; i.e., after all commands or scripts have run. Note that --batch will silence even more output than -q to facilitate using GDB in scripts:
$ # All commands complete without error$ gdb -batch -x hello.gdb myprogramReading symbols from myprogram...hello$ echo $?0$ # Command raises an exception$ gdb -batch -ex "set foo bar"No symbol "foo" in current context.$ echo $?1$ # Demonstrate the order of script execution$ gdb -x hello.gdb -iex 'echo before\n' -ex 'echo after\n' simpleGNU gdb (GDB) Red Hat Enterprise Linux 9.2-2.el8Copyright (C) 2020 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <>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:<>.Find the GDB manual and other documentation resources online at: <>.For help, type "help".Type "apropos word" to search for commands related to "word"...beforeReading symbols from simple...helloafter(gdb) 

Next up

In this article, I've shared details about how GDB starts up, reads scripts (and when it reads scripts), and several startup options commonly used by advanced GDB users.

The next article in the series will take a small detour to explain what debugging information is, how to inspect it, where GDB looks for it, and how to install it in distribution-supplied packages.

Do you have a suggestion or tip related to GDB scripts or startup, or a suggestion for a future topic about how to use GDB? Leave a comment on this article and share your idea with us.

Last updated: February 27, 2024

The GDB developer's GNU Debugger tutorial, Part 1: Getting started with the debugger | Red Hat Developer (2024)


How to do debugging using GDB? ›

Debugging a program that produces a core dump
  1. Compile the program using the following command. g++ testit.c �g �o testit.
  2. Run it normally, you should get the following result: ...
  3. The core dump generates a file called corewhich can be used for debugging. ...
  4. As we can see from the output above, the core dump was produced.

How do I install GDB debugger in Linux? ›

In most Linux distributions, the GDB command comes pre-installed. However, if it's not, you can install it in Debian based distributions like Ubuntu, by running the command sudo apt-get install gdb . For distributions like CentOS that use the RPM package manager, you would run the command sudo yum install gdb .

How to install GDB in Mac? ›

  1. To install gdb, run the following command in macOS terminal (Applications->Utilities->Terminal) sudo port install gdb Copy.
  2. To see what files were installed by gdb, run: port contents gdb Copy.
  3. To later upgrade gdb, run: sudo port selfupdate && sudo port upgrade gdb Copy.

How to install GDB in Red Hat? ›

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

How to run step by step in GDB? ›

To execute one line of code, type "step" or "s". If the line to be executed is a function call, gdb will step into that function and start executing its code one line at a time. If you want to execute the entire function with one keypress, type "next" or "n".

How do I run a debugger code? ›

Launch configurations. To run or debug a simple app in VS Code, select Run and Debug on the Debug start view or press F5 and VS Code will try to run your currently active file.

What is the GDB tool? ›

Gdb is a debugger for C (and C++). It allows you to do things like run the program up to a certain point then stop and print out the values of certain variables at that point, or step through the program one line at a time and print out the values of each variable after executing each line.

How do I set up GDB on VS Code? ›

Setting Up VSCode For C Debugging With GDB
  1. Ctrl+Shift+X to bring up the extension manager.
  2. Search for c/c++
  3. Or download here.
  4. If you're using WSL make sure to install on WSL, not local.
  5. Once it's installed add a debug configuration to your project by running Run > Add Configuration and choose C/C++ .
Jul 22, 2021

How do I run an app with GDB? ›

Starting your program. Use the run command to start your program under GDB. You must first specify the program name (except on VxWorks) with an argument to GDB (see section Getting In and Out of GDB), or by using the file or exec-file command (see section Commands to specify files).

Why does GDB not work on Mac? ›

Debug from the menu will result in Eclipse complaining that an Error with command: gdb --version has occurred. The problem is caused by Apple switching away from GDB, the GNU debugger, to LLDB, the LLVM debugger, in their Xcode toolchain (along with the transition from GCC to Clang).

What is the GDB equivalent on Mac? ›

LLDB is the default debugger in Xcode on macOS and supports debugging C, Objective-C and C++ on the desktop and iOS devices and simulator.

How to install GNU compiler on Mac? ›

Installing GCC for Mac Users
  1. Install Homebrew.
  2. After Homebrew installs, type "brew install gcc" in the terminal.
  3. Once the install completes, attempt to compile a C++ source file using the following command: "g++-12 -Wall -o Program". This example uses g++-12. Change the version as appropriate.

How to install GDB debugger on Windows? ›

Follow below mentioned steps to compile GDB from scratch and install it.
  1. Step-1: Download source code. You can download source code of all release from ...
  2. Step-2: Extract it. $ tar -xvzf gdb-7.11.tar.gz.
  3. Step-3: Configure and Compile it. $ cd gdb-7.11. ...
  4. Step-4: Install GDB.

What is GDB in Ubuntu? ›

The gdb debugger is a command-line debugger where the user can give a series of commands to set a break point, continue execution, examine a variable, set a watch point, etc.

How to install GCC compiler in redhat? ›

How to install GCC 8 and Clang/LLVM 6.0
  1. Become root.
  2. Enable the rhscl , devtools , and optional software repos.
  3. Add the Red Hat Developer Tools key to your system.
  4. Use yum to install devtoolset-8 (GCC 8) and llvm-toolset-6.0 (Clang 6).
  5. Optional: Install the Clang static analysis tools scan-build and clang-tidy .
Mar 5, 2019

How to debug with GDB vscode? ›

The easiest method to debug initialization and constructors is to select the debug points, attach to the executable, and then command “reboot” in MAVProxy. The Launch profiles allow debugging of the binaries directly for initialization tasks and constructors, etc. without using MAVProxy.

How to use GDB for kernel debugging? ›

To configure the debugging infrastructure with GDB, there are three steps:
  1. Compile the kernel with KGDB support.
  2. Start the kernel debugger (KGDB) in the target.
  3. Connect to the kernel debugger using a GDB client in the host.
Jan 15, 2024

How to debug assembly code with GDB? ›

After you've assembled and linked your program using nasm and ld, you can invoke the debugger using the UNIX command: gdb a. out At this point gdb might complain that "no debugging symbols found". Just ignore this particular comment. You can now run your program inside gdb by typing "run" and the gdb prompt.

How do I debug remotely in GDB? ›

To start remote debugging, run GDB on the host machine, and specify as an executable file the program that is running in the remote machine. This tells GDB how to find your program's symbols and the contents of its pure text. Start GDB on the host, and connect to the target (see section Connecting to a remote target).

Top Articles
Latest Posts
Article information

Author: Chrissy Homenick

Last Updated:

Views: 5533

Rating: 4.3 / 5 (74 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Chrissy Homenick

Birthday: 2001-10-22

Address: 611 Kuhn Oval, Feltonbury, NY 02783-3818

Phone: +96619177651654

Job: Mining Representative

Hobby: amateur radio, Sculling, Knife making, Gardening, Watching movies, Gunsmithing, Video gaming

Introduction: My name is Chrissy Homenick, I am a tender, funny, determined, tender, glorious, fancy, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.