Professional Documents
Culture Documents
To facilitate easy
understanding of
coding in GCC
(GNU Compiler
Collection)
Anirban Kundu
Gourab Dolui
Kushal Sarkar
Introduction
Page 2
Dyzan ’08
Compiling a single source file
Compiling a single source file, myprog.c, using gcc is easy—just invoke gcc,
passing the name of the source file as the argument.
$ gcc myprog.c
$ ls –l
-rwxr-xr-x 1 wvh users 13644 Aug 5 16:17 a.out
-rw-r--r-- 1 wvh users 220 Aug5 16:17 myprog.
To define the name of the output file that gcc produces, use the -o option, as
illustrated in the following example:
$ gcc myprog.c -o output_filename
Page 3
Dyzan ’08
Compiling a single source file
$ ls -l
-rw-r--r-- 1 wvh users 220 Oct 5 16:17 myprog.c
-rwxr-xr-x 1 wvh users 13644 Oct 5 16:28 output_filename
If you are compiling multiple source files using gcc, you can simply specify
them all on the gcc command line, as in the following example, which leaves
the compiled and linked executable in the
file named showdate:
$ gcc showdate.c helper.c –o output_filename
To execute a file write
$./a.out
If we change the name of the output file then in oder to execute we write
$./output_filename
Page 4
Dyzan ’08
GCC Command-Line Option
Each command-line option begins with either a hyphen or a pair of hyphens. For
example, the following command line will compile the ANSI standard C program
named muxit.c and produce an unlinked object file named muxit.o.
$gcc -ansi -c muxit.c -o muxit.o
Despite its sensitivity to the grouping of multiple single-letter options, you are
generally free to mix the order of options and compiler arguments on the gcc
command line. That is, invoking gcc as
$gcc -pg -fno-strength-reduce -g myprog.c -o myprog
has the same result as
$gcc myprog.c -o myprog -g -fno-strength-reduce -pg
Page 5
Dyzan ’08
Some Important Command-Line Option
-c
Do not invoke the linker. This option will allow compiling and assembling of
source files into object files, but the linker will not be run to create an executable.
The object files produced will be stored in a file of the same name as the source file
with a .o suffix.
Example :
$ gcc -c showdate.c
$ ls –l
-rw-r--r-- 1 wvh users 208 Oct 5 12:44 showdate.c
-rw-r--r-- 1 wvh users 1008 Oct 5 13:50 showdate.o
-v
Displays the current version number of the compiler and displays all of the
commands used to run each phase of the compile and link process.
Page 6
Dyzan ’08
Some Important Command-Line Option
When used alone, this optionwill display the current version number of the compiler .When used in
combination with the --help option, a complete list of the command line options is displayed.
--help
Print (on the standard output) a description of the command line options understood by gcc.
@file
Read command-line options from file. The options read are inserted in place of the original
@file option. If file does not exist, or cannot be read, then the option will be treated literally, and
not removed. Options in file are separated by whitespace.
Page 7
Dyzan ’08
Some Important Command-Line Option
-s
Stop after the stage of compilation proper; do not assemble. The output is in
the form of an assembler code file for each non-assembler input file specified. By
default, the assembler file name for a source file is made by replacing the suffix
‘.c’, ‘.i’, etc., with ‘.s’. Input files that don’t require compilation are ignored.
-g
Produce debugging information in the operating system’s native format
(stabs,COFF, XCOFF, or DWARF 2). GDB can work with this debugging
information. On most systems that use stabs format, ‘-g’ enables use of extra
debugging information that only GDB can use; this extra information makes
debugging work better in GDB but will probably make other debuggers crash or
refuse to read the program
Page 8
Dyzan ’08
Options for Getting Warning Messages in
GCC
-Wformat option causes gcc to check all calls to printf(), scanf(), and other
functions that rely on format strings, making sure that the arguments supplied
have types appropriate to the format string and that the requested conversions, as
specified in the format string, are sensible.
-Werror option to convert the warning to a hard error that terminates
compilation.
-Wunused option, which catches all unused objects.
Each of the warning options discussed in this section results in similar output that
identifies the translation unit and line number in which a problem is detected, and
a brief message describing the problem.
Example of –Wformat
Consider the program that uses printf() to print some text to the screen.
Page 9
Dyzan ’08
Options for Getting Warning Messages in
GCC
Source Code for the Sample printme.c Application
#include <stdio.h>
#include <limits.h>
int main (void)
{
unsigned long ul = LONG_MAX;
short int si = SHRT_MIN;
printf ("%d\n", ul);
printf ("%s\n", si);
return 0;
}
There are a couple of problems here. The first printf() statement prints the value of the
unsigned long variable ul using an int format string (%d). The second printf() statement
prints the short int variable si using the %s format string (that is, as a string).
Despite these problems, gcc compiles the program without complaint. It even sort of
runs.
Page 10
Dyzan ’08
Options for Getting Warning Messages in
GCC
$ gcc printme.c -o printme
$ ./printme
2147483647
Segmentation fault
As you can see, the program defines the int variable i, but never does anything with it. Here
is GCC’s output when compiling unused.c with no options:
$ gcc unused.c
Here is GCC’s complaint when we use -Wunused:
$ gcc -Wunused unused.c
unused.c: In function 'main':
unused.c:3: warning: unused variable 'i'
Page 12
Dyzan ’08
Debugging Your Program
This is one of the areas where gdb comes in handy. By running the program
under gdb, we can find out the exact line that the program is crashing on.
Page 15
Dyzan ’08
Debugging Your Program
gdb is now waitng for the user to type a command. We need to run the
program so that the debugger can help us see what happens when the program
crashes. Type run at the (gdb) prompt. Here is what happens when I run this
command:
Page 16
Dyzan ’08
Debugging Your Program
(gdb) run
Starting program: /home/newren/examples/main
Program received signal SIGSEGV, Segmentation fault.
0x0804835b in print_scrambled (message=0x0) at main.c:8
1 printf("%c", (*message)+i);
The program crashed so lets see what kind of information we can gather.
Inspecting crashes
So already we can see the that the program was at line 8 of main.cc, that
this points to 0, and we can see the line of code that was executed. But we also
want to know who called this method and we would like to be able to examine
values in the calling methods. So at the gdb prompt, we type backtrace which
gives me the following output:
Page 17
Dyzan ’08
Debugging Your Program
(gdb) backtrace
#0 0x0804835b in print_scrambled (message=0x0) at main.c:8
#1 0x080483c3 in main () at main.c:20
Reading backtraces is fairly straightforward. The data associated with each function
call in the list is known as a frame. The outermost frame is the initial function
that your program started in, and is printed at the bottom of the list. Each frame is
given a number (0, 1, 2, etc.). Following the frame number is an associated
memory address, which is almost entirely useless and which you can ignore.
Then each frame contains the name of the function that was called, its
arguments, the name of the file where the function appears, and line number.
So, the stack trace for our program says that at line 20 of gdb-example.c in
function main, the print_scrambled function was called--and that the program got
to line eight of gdb-example.c inside the print_scrambled function.
Page 18
Dyzan ’08
Debugging Your Program
Page 19
Dyzan ’08
Debugging Your Program
Example :
(gdb) run
Starting program: /home/newren/examples/main
Program received signal SIGSEGV, Segmentation fault.
0x0804835b in print_scrambled (message=0x0) at mainc:8
8 printf("%c", (*message)+i);
(gdb) list
3 void
4 print_scrambled(char *message)
5 {
6 int i = 3;
7 do {
8 printf("%c", (*message)+i);
9 } while (*++message);
10 printf("\n");
11 }
12
Page 20
Dyzan ’08
Debugging Your Program
Page 21
Dyzan ’08
Debugging Your Program
(gdb) info args
message = 0x0
(gdb) up
#1 0x080483c3 in main () at gdb-example.c:20
20 print_scrambled(bad_message);
(gdb) list
15 {
16 char * bad_message = NULL;
17 char * good_message = "Hello, world.";
18
19 print_scrambled(good_message);
20 print_scrambled(bad_message);
21 }
Page 22
Dyzan ’08
Debugging Your Program
print [/f ] [expr] / p [/f ] [expr] : show value of expr [or last value $]
according to format f:
x hexadecimal
d signed decimal
u unsigned decimal
o octalt binary
c character
f foating point
continue [count] : continue running; if count specified,
step [count] : execute until another line reached; repeat count times if specified
next [count] : execute next line, including any function calls
return [expr] : pop selected stack frame without executing [setting return value]
jump line : resume execution at specified line number
jump *address : or address
Page 23
Dyzan ’08
Debugging Your Program
Example :
(gdb) run
Starting program: /home/newren/examples/gdb-example
Breakpoint 1, main () at gdb-example.c:16
16 char * bad_message = NULL;
(gdb) print bad_message
$1 = 0x8048410 "U\211%G%@VS"
(gdb) next
17 char * good_message = "Hello, world.";
(gdb) print bad_message
$2 = 0x0
(gdb) next
19 print_scrambled(good_message);
Page 24
Dyzan ’08
Debugging Your Program
(gdb) next
20 print_scrambled(bad_message);
(gdb) step
print_scrambled (message=0x0) at gdb-example.c:6
6 int i = 3;
(gdb) step
8 printf("%c", (*message)+i);
(gdb) step
Program received signal SIGSEGV, Segmentation fault.
0x0804835b in print_scrambled (message=0x0) at gdb-example.c:8
8 printf("%c", (*message)+i);
(gdb) print (*message)+i
Cannot access memory at address 0x0
Page 25
Dyzan ’08
Debugging Your Program
To do anything really useful with gdb, you need to set breakpoints which
temporarily pause your program's execution so you can do useful debugging
work like inspecting variables and watching the program's execution in an
atomic line-by-line fashion. This right here is the magic of a symbolic
debugger.
Breakpoints come in three flavors:
٭A breakpoint stops your program whenever a particular point in the program
is reached.
٭A watchpoint stops your program whenever the value of a variable or
expression changes..
٭A catchpoint stops your program whenever a particular event occurs.
Page 26
Dyzan ’08
Debugging Your Program
We'll first concentrate on learning how to set breakpoints, and then we'll debug the
program.
Page 27
Dyzan ’08
Debugging Your Program
By Function Name
The "break main" command sets a breakpoint at the top of main(), which
happens to be line 8 of main.c.
(gdb) break main
Breakpoint 1 at 0x8048464: file main.c, line 8.
By Line Number
(gdb) break 9
Breakpoint 2 at 0x804846b: file main.c, line 9
By Filename And Line Number
(gdb) break main.c:10
Breakpoint 3 at 0x80483fd: file main.c, line 10.
Page 28
Dyzan ’08
Debugging Your Program
Removing Breakpoints
Just as you can set breakpoints, you can also remove them. There are numerous
ways to remove a breakpoint:
If you want to remove the breakpoint by its location, use clear.
If you want to remove the breakpoint by its identifier, use delete.
(gdb) clear fgets.c:10
Deleted breakpoint 3
(gdb) clear 9
Deleted breakpoint 2
(gdb) clear main
Deleted breakpoint 1
The delete command deletes breakpoints by identifier, as opposed
to clear which removes breakpoints based on their location. In
fact, delete n deletes the breakpoint with identifier n.
Page 29
Dyzan ’08
Debugging Your Program
Listing Breakpoints
But how do you remember the identifiers for your breakpoints, or even where your
breakpoints were set to begin with? There's a command, info breakpoints which lists all
your breakpoints, their identifiers, and lots more information.
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048464 in main at main.c:6
breakpoint already hit 1 time
2 breakpoint keep y 0x0804846b in main at main.c:9
breakpoint already hit 1 time
3 breakpoint keep y 0x08048477 in main at main.c:12
Page 30
Dyzan ’08
Debugging Your Program
Setting watchpoints
• watch EXPR
Set a watchpoint for an expression. GDB will break when EXPR is
written into by the program and its value changes.
Eg : watch (*message)+i
• rwatch EXPR
Set a watchpoint that will break when the value of EXPR is read by
the program.
• awatch EXPR
Set a watchpoint that will break when EXPR is either read from or
written into by the program.
• info watchpoints
This command prints a list of watchpoints, breakpoints, and
catchpoints; it is the same as `info break'
Page 31
Dyzan ’08
Some Important Tips about GCC
Page 32
Dyzan ’08
Thank you
Dyzan ’08