The GNU Debugger (gdb) is a powerful tool that allows developers to see what is happening inside a program while it runs or what the program was doing when it crashed. This guide will show you how to use gdb to debug a simple C program in a Linux environment.

Step 1: Create a simple C program that we will debug. Open your terminal and use vim or your preferred text editor to create a new file named test.c.

vim test.c

Step 2: Write the following code in test.c:

#include <stdio.h>

int main() {
    int i = 5;
    float f = 5.5;
    i = i + 3;
    f = f + 2.2;
    printf("Value of i and f are: %d and %f\n", i, f);
    return 0;
}

Ensure that all semicolons are correctly placed to avoid compilation errors. Press Escape to switch to command mode in vim, then type :wq to save the file and exit the editor.

Step 3: Compile the program and verify that it runs correctly. Enter the following commands in your terminal:

gcc test.c -o test
./test

You should see the following output:

Value of i and f are: 8 and 7.700000

Step 4: To enable debugging support, recompile the program with the -g flag, which includes debug information in the executable:

gcc test.c -g -o test

Step 5: Launch gdb to start debugging the executable:

gdb test

This will open the gdb console, where you can enter debugging commands. To see a list of available commands, type:

(gdb) help

You can get help on a specific class of commands by typing help <class_name>. Use apropos <keyword> to search for commands related to a specific keyword.

Step 6: Set a breakpoint at the beginning of the main function so that the program stops there when you run it:

(gdb) break main

Now, run the program within gdb to execute it until it reaches the breakpoint:

(gdb) run

Step 7: To set a breakpoint at a specific location within the main function, use:

(gdb) break *main + 4

This sets a breakpoint at the fourth instruction inside main. To proceed through the program step by step, use the step command:

(gdb) step

For example, stepping through the code might display:

5: float f = 5.5;

Step 8: To display the value of a variable while debugging, use the display command:

(gdb) display i

This will show the value of i each time the program stops. If you want to change the value of a variable, use the set variable command:

(gdb) set variable i=10

Now, when you display i, it will reflect the updated value:

(gdb) display i
7: i = 10

Step 9: To view the assembly code of the main function, use the disassemble command:

(gdb) disassemble main

The arrow in the assembly output indicates the current instruction where the debugger is paused.

Step 10: To jump to a specific line or instruction in the code, use the jump command:

(gdb) jump *main + 2

This command forces the debugger to jump to the specified instruction. Be cautious when jumping over code that initializes variables, as it may lead to errors when those variables are accessed. For example:

Continuing at 0x400528.

Breakpoint 2, 0x000000000040052a in main () at test.c:3
3	int main() {
1:	i = <error: Cannot access memory at address 0xffffdc48>
2:	f = <error: Cannot access memory at address 0xffffdc4c>

These fundamental gdb commands provide a starting point for debugging programs in Linux. As you become more comfortable with gdb, you can explore its advanced features to perform more complex debugging tasks.