Categories
Linux

How to Use GNU Debugger in Linux

GNU Debugger is used to debug a program, to analyze crash, or to see what the program does at a particular point. It was developed by the GNU Project in the 1980s and has been one of the most widely used command line debuggers as well as one of the most popular GNU software.

Let us first write a small C program which we will then debug. To get started, create a new .c file using vim or any editor of your choice:

vim test.c

Create the following C program:

#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;
}

Press Escape to go to vim command mode. Then type :wq to save the program and exit.

Compile and see if the program runs:

gcc test.c -o test
./test
Value of i and f are: 8 and 7.700000

To enable debugging support in a program, we compile it with -g flag. If the flag is not used, user can still debug the program, albeit with limited options.

gcc test.c -g -o test

To start debugging our executable file test in gdb, we run:

gdb test

It will open the gdb console, where you can type the gdb commands. To see a list of commands use the help command.

$(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.

You can then type help class_name to see commands belonging to that class. To search commands using a substring, use apropos substring.

To set a breakpoint when the program enters a function, run:

$(gdb) break main

Here we set a breakpoint at the only function in our code, i.e. main. Use the command run to execute the program till next breakpoint, or till exit.

$(gdb) run

To set a breakpoint at a particular location in a function, use:

break *main + 4

This will set up a breakpoint at the 4th line of function main.

Now, to step over the flow of program to next code line, simply run the step command.

$(gdb) step
5: float f = 5.5;

To display contents of a variable, run display <variable_name>.

$(gdb) display i
6: i = 5

To modify contents of a variable, which might be required to analyze the run of a program under specific values of a variable, run set variable <variable_name>=Expression.

$(gdb) set variable i=10
$(gdb) display i
7: i = 10

Here, the ‘Expression’ can be any valid (arithmetic / logical) expression. For sake of simplicity we just assign another value (10) to variable i.

To print the assembly code for the program, use command disassemble functionname:

Use just disassemble to print assembly code for whole program. Note the arrow at a particular line in the assembly code. It denotes that the debugging session is currently paused at that particular memory location (i.e., that line of code).

To jump the debugger at a particular line of code, run:

$(gdb) jump *main + 2
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>
3: h = (void *) 0x0
4: main = {int ()} 0x400526 <main>
5: i = <error: Cannot access memory at address 0xffffdc48>

This will make the debugger jump at memory location of the 2nd line of code in function main. Note that here I jumped from start of main to directly second location. Hence, variable i was never set, which results in the debugger throwing error that it cannot access the memory contents at address of variable i.


These are some of the basic commands which can help you get started with debugging an executable file in Linux. We hope you find the information on this page helpful.