Tutorial of gcc and gdb
The graphical user interface (GUI) domainates the current operating environments for personal computing. However, there are still tons of powerful tools, such as gcc and gdb, using the traditional text-based interface. Now, let's turn on the terminal within Linux, FreeBSD, Mac OS X, or any other UNIX-like operating system to discover the power of command-line tools!
*If you don't have any linux machine available, please try to login ieng6.ucsd.edu and ieng9.ucsd.edu with ssh clients. If you have problem login these machines, please contact Hung-Wei.
Contents
gcc
gcc is the C and C++ compiler developed by GNU project. It is widely adopted as the default compiler of UNIX-like systems. If you are using a Mac, you may also get gcc by installing Xcode (Developer) Tools in the Mac OS X installation Disc #1.
Basic Usage
Assume that we have a C source file "garbage.c" with the content of shown below:
1: #include 2: #include 3: 4: int main(int argc, char **argv) 5: { 6: int a, b, i; 7: float c; 8: a = atoi(argv[1]); 9: b = atoi(argv[2]); 10: c = a/b; 11: printf("%d/%d = %f\n",a,b,c); 12: return 0; 13:}The basic way of compiling garbage.c into an executable file called "garbage" is:
- gcc -o garbage garbage.c
If you are interested about how the assembly code of garbage.c look like, you can also generate the assembly code by replacing the "-o garbage" option with "-S" as:
- gcc -S garbage.c
- Handout on x86 ISA.
- A good document on x86 ISA.
- A good document on x86 ISA.
- A good document on x86 ISA.
Frequently Used Options
In addition to the basic usage, gcc also provides options that help you optimize or debug your code. For example, you may:- Compile your code with debugging information:
- gcc -g -o garbage garbage.c
- Compile your code with optimizations:
- gcc -On -o garbage garbage.c
- For other optimization/debug options, you may use
- man gcc
gdb
gcc is a debugger by GNU project. Gdb can step through your source code line-by-line or even instruction by instruction. You may also watch the value of any variable at run-time. In additon, it also helps to identify the place and the reason making the program crash.
Basic Usage
All program to be debugged in gdb must be compiled by gcc with the option "-g" turning on. Continue with the "garbage" example, if we want to debug the program "garbage", we can simply start gdb by:
- gdb ./garbage
GNU gdb Red Hat Linux (6.3.0.0-1.162.el4rh) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu"..."/home/h1tseng/garbage": not in executable format: File format not recognized (gdb)
To start running and debugging the program, we can simply type the "run" command after the (gdb) prompt as below:
(gdb) run
If the program takes arguments such as "garbage arg_1 arg_2", we may start running the program with these arguments as:(gdb) run arg_1 arg_2
Breaking Program
To inspect the current state of program exeution, we need to break the execution of debugging program in gdb. At any point, we may use ctrl-c to interrupt the running program. However, ctrl-c is hard to help breaking our program at a specific point. Therefore, gdb provides the "breakpoint" function that allows us to break debugging program at the "breakpoint" set by ourselves. Gdb allows the breakpoint to be set to any source code line, function, or even any instruction.- Break by line: to break the program at the beginning of a certain line, we can use the command "break source_filename:line_number". For example, if we want to break at the beginning of main function in garbage.c, we can do as below:
(gdb) break garbage.c:8 Breakpoint 1 at 0x1f7b: file garbage.c, line 8.
- Break by function: to break the program at the beginning of a certain function, we can use the command "break source_filename:function_name()". For example, if we want to break at the beginning of main function in garbage.c, we can also try below:
(gdb) break garbage.c:main Breakpoint 1 at 0x1f7b: file garbage.c, line 8.
- Break by instruction: to break the program at the beginning of a certain machine instruction, we can use the command "break *PC". For example, if we want to break at the beginning of main function in garbage.c, we can also try below:
(gdb) break *0x1f7b Breakpoint 1 at 0x1f7b: file garbage.c, line 8.
To show the current breakpoints we have, we may use the "info breakpoint" command as:
(gdb) info breakpoint Num Type Disp Enb Address What 1 breakpoint keep y 0x00001f7b in main at garbage.c:8
To disable a breakpoint we have, we may use the "disable breakpoint_number". To re-enable disabled breakpoint, we can turn it on by "enable breakpoint_number". To remove a breakpoint, we can use "delete breakpoint_number" or replace the "break" with "clear" command as we create these breakpoints.
(gdb) clear garbage.c:8 Deleted breakpoint 1
To resume the exeution of the interrupted program, we can use the "continue" or "c" command.
Stepping through program
Once a running program is interrupted in gdb, we can step the program to inspect how the program is executed. Gdb provides several step commands to allow stepping program with different granularities:- s: the debugger will step to the next line in the source code. For example, using the s command, the program will step through line 9 from line 8 after the program interrupted by breakpoint 1.
(gdb) run Starting program: /Users/bunny/Desktop/cse141/garbage Reading symbols for shared libraries ++. done Breakpoint 1, main (argc=1, argv=0xbffff2bc) at garbage.c:8 8 a = atoi(argv[1]); (gdb) s 9 b = atoi(argv[2]);
- si: the debugger will step to the next instruction in the compiled code. For example, using the si command, the program will step through PC 0x00001f91 from 0x00001f8e.
(gdb) si 0x00001f8e 9 b = atoi(argv[1]); (gdb) si 0x00001f91 9 b = atoi(argv[1]);
- n: the debugger will step to the next source line. Each function call will be treat as a single source code line.
Inspect variables/register value
Once a running program is interrupted in gdb, we can also inspect the value of a variable using the "print" command.
If we are interested about the current value of variable a, we can simply "print variable_name". For example, after line 8 is executed, we can inspect if the atoi function correctly translate the characters to integer as below:
Starting program: /Users/bunny/Desktop/cse141/garbage 88 2 Breakpoint 1, main (argc=3, argv=0xbffff2ac) at garbage.c:8 8 a = atoi(argv[1]); (gdb) n 9 b = atoi(argv[2]); (gdb) print a $10 = 88
Similiarly, if we are interested about the current value of a register, we can simply "print $register_name". For example, after line 8 is executed, we can inspect $eax as:
(gdb) print $eax $11 = 88
If we are interested about all the register values, we can use "info registers" command to display the value in all registers.
(gdb) info registers eax 0x58 88 ecx 0x0 0 edx 0xccccccc 214748364 ebx 0x1f76 8054 esp 0xbffff240 0xbffff240 ebp 0xbffff288 0xbffff288 esi 0x0 0 edi 0x0 0 eip 0x1f8a 0x1f8a eflags 0x282 642 cs 0x17 23 ss 0x1f 31 ds 0x1f 31 es 0x1f 31 fs 0x0 0 gs 0x37 55
- Compile your code with debugging information: