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.
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.
Assume that we have a C source file "garbage.c" with the content of shown below:
1: #includeThe basic way of compiling garbage.c into an executable file called "garbage" is: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:}
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 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.
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:
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) runIf 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
(gdb) break garbage.c:8 Breakpoint 1 at 0x1f7b: file garbage.c, line 8.
(gdb) break garbage.c:main Breakpoint 1 at 0x1f7b: file garbage.c, line 8.
(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.
(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]);
(gdb) si 0x00001f8e 9 b = atoi(argv[1]); (gdb) si 0x00001f91 9 b = atoi(argv[1]);
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 0x1f8aeflags 0x282 642 cs 0x17 23 ss 0x1f 31 ds 0x1f 31 es 0x1f 31 fs 0x0 0 gs 0x37 55