How to Get Started With GNU Debugger on Linux: A Crash Course
Debugging is an essential skill for any programmer or software developer. Knowing how to efficiently debug code allows you to quickly identify and fix issues in your programs.
The GNU Debugger (GDB) is a powerful, open-source debugging tool available on Linux and other Unix-based systems. It allows you to interactively debug programs written in languages like C, C++, Rust, Go, and more by controlling program execution and inspecting variable values.
In this comprehensive guide, you'll learn how to use GDB to debug programs on Linux by walking through various examples.
Installing GDB on Linux
GDB comes pre-installed on most Linux distributions. To verify if you already have it, run:
gdb --version
If not installed, use your distribution's package manager to install it.
For Debian/Ubuntu:
sudo apt install gdb
For RHEL/CentOS:
sudo yum install gdb
For Arch Linux:
sudo pacman -S gdb
Preparing a Sample Program
To learn GDB, you need a program to debug. Here's a simple "guess the number" game in C:
#include <stdio.h>
#include <stdlib.h>
int main() {
int secretNum = 5;
int guess;
printf("Guess the secret number (1-10): ");
scanf("%d", &guess);
if(guess == secretNum) {
printf("You guessed correctly!");
} else {
printf("Sorry, try again.");
}
return 0;
}
Save the above as guess.c
and compile it into a binary with debug symbols:
gcc -g guess.c -o guess
The -g
flag includes debugging information in the compiled program. This allows GDB to map code to source lines.
Starting GDB
To debug the guess
program with GDB, run:
gdb guess
This will start GDB in interactive mode. You'll see the (gdb)
prompt waiting for your commands.
To directly execute the program inside GDB, use the run
command:
(gdb) run
This will start the program execution. Provide input when prompted and the program will run normally. Use Ctrl + C
to halt execution and return to the GDB prompt.
Alternatively, you can directly load and run the program by:
gdb guess --args ./guess
Setting Breakpoints
A breakpoint stops execution at a specific line or function and returns control to GDB. This allows you to inspect the program state at that point.
To set a breakpoint at the main()
function, type:
(gdb) break main
You can also set a breakpoint on a specific line number:
(gdb) break 8
This will break line 8 of the source code.
Run info breakpoints
to see the currently set breakpoints.
When the program hits a breakpoint, execution will pause and you'll be able to inspect variables, execute code line-by-line, etc.
Stepping Through Code
Once stopped at a breakpoint, you can step through code one line at a time using:
step
- Step to the next line of codenext
- Step over the current linefinish
- Finish execution of the current function
For example, on hitting the breakpoint at main()
:
(gdb) step
9 int secretNum = 5;
(gdb) print secretNum
$1 = 5
(gdb) next
10 int guess;
(gdb) finish
Run till exit from #0 main () at guess.c:10
0x0000555555555167 in __libc_start_main (main=0x00005555555550d9 <main>, argc=1, argv=0x7fffffffe518, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffe508) at ../csu/libc-start.c:342
342 ../csu/libc-start.c: No such file or directory.
This allows you to walk through the program flow and observe the changes in state.
Viewing Variables
To inspect a variable value in GDB, use the print
command:
(gdb) print guess
$1 = 4
You can also view all variables in the current scope:
(gdb) info locals
secretNum = 5
guess = 4
Examining the Stack
The stack contains valuable debugging information like parameter values, return addresses, and local variables of function calls.
To examine the stack trace, use:
(gdb) backtrace
#0 main () at guess.c:14
#1 0x00007ffff7a0530a in __libc_start_main (main=0x5555555550d9 <main>, argc=1, argv=0x7fffffffe518, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe508) at ../csu/libc-start.c:342
#2 0x00005555555550a8 in _start ()
This shows the sequence of function calls currently active. You can combine it with other commands like frame
and info locals
to inspect a particular stack frame.
Debugging Core Dumps
When a program crashes unexpectedly, it can generate a core dump file containing the program state at the time of the crash.
Examine core dumps in GDB using:
gdb program_name core_file
This will load the program and core dump. You can then inspect variables, stack trace etc. to uncover the cause of the crash.
Debugging Multi-threaded Apps
To debug multi-threaded applications, first list the threads:
(gdb) info threads
Id Target Id Frame
2 Thread 0x7ffff7fc7700 (LWP 8189) "mythread" pthread_join (threadid=140737354072576, thread_return=0x7fffffffd4c0) at pthread_join.c:90
1 Thread 0x7ffff7fc5700 (LWP 8188) "mythread" 0x00007ffff7a07aa1 in __GI___pthread_timedjoin_ex (threadid=140737354072576, thread_return=0x7fffffffd4c0, abstime=0x0, clockid=<optimized out>) at pthread_join_common.c:89
* 1 Thread 0x7ffff7dd9700 (LWP 8187) "guess" 0x0000555555555193 in main () at guess.c:19
This shows the active threads in the program.
You can switch context to a specific thread using:
(gdb) thread 2
[Switching to thread 2 (Thread 0x7ffff7fc7700 (LWP 8189))]
#0 pthread_join (threadid=140737354072576, thread_return=0x7fffffffd4c0) at pthread_join.c:90
90 return SYSCALL_NOERROR;
Now you can inspect this thread's stack, variables etc. independently.
Summary
GDB is a powerful tool that should be in every developer's debugging toolkit. Its interactive nature, combined with commands like breakpoints, stepping, and inspection of variables and stack traces make it invaluable for understanding program execution flows and identifying issues.
Some key topics we covered:
Installing and starting GDB
Setting breakpoints
Stepping through code line-by-line
Printing variables and examining stack traces
Debugging core dumps and multi-threaded programs
This was just a short overview of GDB's capabilities. For more advanced use and customization of GDB, refer to the official GDB documentation.
Happy debugging!
Subscribe to my newsletter
Read articles from Pratik M directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Pratik M
Pratik M
As an experienced Linux user and no-code app developer, I enjoy using the latest tools to create efficient and innovative small apps. Although coding is my hobby, I still love using AI tools and no-code platforms.