C gdb (GNU Debugger)

beginner
19 min

C gdb (GNU Debugger)

Welcome to our comprehensive guide on using the GNU Debugger (gdb) in C programming!

This lesson is designed for beginners and intermediates who are eager to learn about debugging their C programs effectively.

šŸŽÆ What is gdb?

gdb is a powerful debugging tool used primarily for C, C++, and Fortran programs. It allows you to inspect the execution of your code, step by step, find and fix errors, and understand the flow of your program.

šŸ“ Why use gdb?

Debugging is an essential part of programming, especially when dealing with complex code. gdb helps you understand why your code isn't working as expected, making it an indispensable tool for every programmer.


Getting Started with gdb

Installing gdb

šŸ“ Note: gdb is usually pre-installed on most Unix-based systems (like Linux and macOS). If you're using a Windows system, you can download and install MinGW or Cygwin, which include gdb.


Basic gdb Commands

Starting gdb

šŸŽÆ Command: gdb your_program

Replace your_program with the name of your C program.


Listing Source Code

šŸŽÆ Command: list filename:line_number

This command displays the source code around the specified line number.


Running and Debugging

šŸŽÆ Command: run [arguments]

This command runs your program with the specified arguments.


Breakpoints

šŸŽÆ Command: break filename:line_number

Setting a breakpoint allows you to pause the execution of your program at a specific line.


Stepping Through Code

šŸŽÆ Commands: step, next, continue

step moves to the next line of code, executing any functions calls along the way. next moves to the next line without executing function calls. continue resumes the execution of your program until the next breakpoint or program termination.


Advanced gdb Features

Watch Expressions

šŸŽÆ Command: watch expression

Watch expressions allow you to monitor the value of a specific variable during program execution.


Stack Traces

šŸŽÆ Command: backtrace

This command displays the call stack, showing the sequence of function calls leading to the current execution point.


Quitting gdb

šŸŽÆ Command: quit

Exits gdb and returns you to your terminal.


Practice Time šŸ’”

Quick Quiz
Question 1 of 1

Which command is used to run a program with gdb?


Example 1: Debugging a Simple Program

Let's debug a simple C program that calculates the sum of two numbers.

c
#include <stdio.h> int main(int argc, char *argv[]) { int a = 5; int b = 10; int sum = a + b; printf("The sum is: %d\n", sum); return 0; }
  1. Start gdb with the program: gdb your_program
  2. Run the program: run
  3. Set a breakpoint at the line where the sum is calculated: break 8
  4. Continue the execution: run
  5. Step through the code: step
  6. Inspect the value of the sum variable: print sum

Example 2: Debugging a Real-World Program

Here's an example of debugging a simple linked list program. We'll find and fix a bug causing a segmentation fault.

c
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } Node; Node* create_node(int data) { Node* new_node = (Node*)malloc(sizeof(Node)); new_node->data = data; new_node->next = NULL; return new_node; } void insert_at_head(Node** head, int data) { Node* new_node = create_node(data); new_node->next = *head; *head = new_node; } void print_list(Node* head) { Node* current = head; while (current != NULL) { printf("%d -> ", current->data); current = current->next; } printf("NULL\n"); } int main() { Node* head = NULL; insert_at_head(&head, 1); insert_at_head(&head, 2); insert_at_head(&head, 3); print_list(head); return 0; }
  1. Start gdb with the program: gdb your_program
  2. Run the program: run
  3. You'll notice a segmentation fault. To debug this, set a breakpoint before the print_list function: break print_list
  4. Continue the execution: run
  5. Step through the code: step until you reach the print_list function
  6. Inspect the value of the head variable: print head
  7. You'll find that the head is NULL, indicating an issue with the insertion at the head function. To fix this, change the following line in the insert_at_head function:
c
*head = new_node;

to

c
new_node->next = *head; *head = new_node;

Now, recompile and re-run the program with gdb:

sh
gcc -g your_program.c -o your_program gdb your_program run

You should now see the linked list printed correctly.


And that's a wrap! You've learned the basics and some advanced features of gdb for debugging C programs. Happy coding! šŸ’»šŸŽ‰