If you never use GDB (The GNU Project Debugger), well, you should! It’s easy to underestimate its usefulness when debugging programs. Below you’ll find some very basic commands that will get you started:
First of all you need to compile/assemble your program with the -g flag, which will include in the executable the necessary code to run with GDB.
gcc test.c -o test -g
Once you have the executable you can load it on GDB with the command:
gdb ./test
Alternatively you could also start gdb by itself and then load the file with “file test”. GDB is ready to go, and to execute the program you just need to use the “run” command.
run
If you do this now, however, the program will execute until the end, and you won’t gain much information (as this is like running the program without gdb).
To make it more useful you need to use breakpoints, which are points where the execution of the program will be stopped. You can see the source code with the “list” command.
list
To create a new breakpoint you use the “b” command:
b *0x26 (breakpoint at memory location 0x26)
b 48 (breakpoint at line 48 of the program)
b function (breakpoint at entry of function)
The three cases above should be enough for most programs. If you need to get fancier with breakpoints here’s a post that lists all you can do with them.
Now you can run the program and it will stop at the breakpoint. To continue execution now you have four main options:
si
SI stands for step instruction, and it will execute only one new instruction of the machine code, then stop.
step
Similar to SI, but instead of executing one machine instruction “step” it will execute one line of your source code (which may translate into more than one machine instructions).
next
“Next” will run the program until the next line of the source code. The difference to “step” is that is the next instruction is a function call it will execute the whole function and stop before the next line.
continue
“Continue” will execute the program until the end or until a breakpoint is found.
At any given time you examine the registers with the “info registers” command.
info r
You can also examine the value of variables or memory locations with the “print” command:
print x (prints the value of memory x)
print *0xA8 (prints the value of memory location 0xA8)
print *(char *) 0x2034 (prints the byte at 0x2034 and shows what char is that in ASCII)
If you want to run your program using a source file as input you can run it like this:
run < input.txt