VoyForums
[ Show ]
Support VoyForums
[ Shrink ]
VoyForums Announcement: Programming and providing support for this service has been a labor of love since 1997. We are one of the few services online who values our users' privacy, and have never sold your information. We have even fought hard to defend your privacy in legal cases; however, we've done it with almost no financial support -- paying out of pocket to continue providing the service. Due to the issues imposed on us by advertisers, we also stopped hosting most ads on the forums many years ago. We hope you appreciate our efforts.

Show your support by donating any amount. (Note: We are still technically a for-profit company, so your contribution is not tax-deductible.) PayPal Acct: Feedback:

Donate to VoyForums (PayPal):

Login ] [ Contact Forum Admin ] [ Main index ] [ Post a new message ] [ Search | Check update time | Archives: 1[2] ]


[ Next Thread | Previous Thread | Next Message | Previous Message ]

Date Posted: 04:17:28 07/17/07 Tue
Author: Anandan
Subject: gcc basics part2
In reply to: Anandan 's message, "C Programming Development Environment on Unix" on 00:23:55 07/17/07 Tue


Generating debug symbol
=======================
The GNU Debugger (gdb) is a powerful debugging tool. These tools provide the programmer, with powerful ways to trace the exe
cution of a program and to isolate problems. Now you will learn how to compile your programs such that gdb can work with the
m.

Before you can use gdb properly with your programs, you need to compile them with debugging symbols. When you do this, gcc i
nserts extra information into the object files (.o) and executable files that it generates. This extra information enables g
db to determine the relations between the compiled code and the lines in your source file. Without that information, gdb wou
ld not be able to determine which line of code your program is executing at any given time.
It is possible to remove debug symbols from an already compiled program by using the strip(1) utility. This means that it's
not necessary to recompile your programs after you're done debugging them. The uses of debug symbols can be incompatible wit
h optimizations. Because gcc can sometimes modify the order in which instructions are performed to gain speed benefits, it i
s best to avoid using the -0 or optimization-enabling -f options.

To generate debugging symbols, use the -g options to gcc. To generate default set of debugging options -
$gcc -g -Wall -o test1 test1.c

To generate more debugging information use
$gcc -ggdb3 -Wall -o test1 test1.c
The 3 means level-3 debugging information (the maximum possible debugging information with -ggdb3). Level 3 adds information
such as macro definitions to the debugging information, which can be valuable in certain situations.

A small Example to use gdb debugger (for core dump issue)

//FileName: crash.c
#include
int main(void){
int input = 0;
printf("Enter an integer: ");
scanf("%d", input);
printf("Twice the number you entered is %d.\n", 2*input);
return 0;
}
Without debug options
$gcc -Wall -o crash crash.c
$./crash
Enter an integer: 10
Segmentation fault
Now the program crashed. Next compile with debug options:

$gcc -ggdb3 -Wall -o crash crash.c

Now you need to enable core dumps. Under the Bash shell, you can do so by running:
$ulimit -c unlimited

Runthe program again:
$./crash
Enter an integer: 12
Segmentation fault (core dumped)
It crashed again. Next step is to load the progam and core file into gdb for analysis:

$gdb crash core.16529
GNU gdb Red Hat Linux (6.3.0.0-1.96rh)
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"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

Core was generated by `./crash'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x00381ec7 in _IO_vfscanf_internal () from /lib/tls/libc.so.6
(gdb)
The last several lines are the ones that are interesting. First the fact that the program crashd because of a segmentation fault indicates that some memory issue was probably at hand. Then, the fact that the crash occurred in a function containingthe word scanf(_IO_vfscanf_internal ()) is a hint. To get more detailed information enter bt at the gdb prompt:

(gdb)bt
#0 0x00381ec7 in _IO_vfscanf_internal () from /lib/tls/libc.so.6
#1 0x00388496 in scanf () from /lib/tls/libc.so.6
#2 0x080483df in main () at crash.c:6
(gdb)
Skipping pas the first two lines, which occur inside of the C library, you see something that occurred on line 6 of crash.c.
Now one more check:
(gdb)frame 2
#2 0x080483df in main () at crash.c:6
6 scanf("%d", input);
(gdb) print input
$1 = 0
(gdb)

First you switch to frame 2(the value on the appropriate line of the bt output). Then you ask gdb to display the value of the variable input just before the crash. It is still zero - the value 12 was not stored into it, confirming the suspicion that the call to the scanf() function caused the crash.

Now the problem is isolated, you can exit the gdb by typing q
(gdb)q
$

The line fixed must be: scanf("%d", &input);
--------------------------------------------------

Big picture of gcc:
------------------
Running gcc does much more than run the compiler: A compiler simply translates the source code to assembly code. After that, an assembler must be run to generate object code. Finally, a linker must be run to bind the object code together with all the things necessary for it to run. So far, gcc has taken care of these extra details for you automatically.

C Compiler uses gcc and C++ compiler uses g++ to do the compilation.
The C preprocesor cpp command is responsible for the evaluation of macros, conditional compilation, and other tasks that need to take place before the code is passed through the compiler properly. In general, any of the # syntax items, and the code that they act upon is preprocessed by cpp. For instance, consider the following code snippet:
#define FOO (5*2)
printf("%d\n", FOO*2);
After running through cpp, the code will be modified to read:
printf("%d\n", (5*2)*2);
So cpp removes comments, interprets macros, handles include files, handles #if and #ifdef statements, and almost anything else that starts with a # sign. The gcc compiler normally calls cpp automatically; you also can call it with gcc -E or by using cpp on the command line.

There are multiple parts that have to be brought to form the final executable. Items such as the C library, program initialization code, and so on, must be included. In such cases the linker combines all the modules together, brings in the C library and startup code, and generates the finished product.

Normally the linker ld is invoked by the compiler to generate the final executable. You can use ld manually, however, if you want more fine-grained control over the linking process.

When gcc compiles your code, it generates assembly code. The job of as (GNU Assembler) is to take this assembly code and generate the object (binary) code that is used to form the .o files, libraries, or the final executable.The as is rarely called independently; rather, it is almost always invoked by gcc.

The Archiver ar is used to build static libraries. This program is used for comb ining several small files into one large file. You can combine sever .o files into a single .a file.

Other related tools are discussed under separate headings.

Working with large projects:
============================
Assume you have divided a project into a number of modules. There are a number of ways to use the gcc to get the final executable file. You have 3 programs io.c, init.c and compute.c. To compile the entire program the simplistic way, one could useis:
$gcc -Wall -o myprogram io.c init.c compute.c
But for minor changes also if you use this command, you would be recompiling the entire program and there is not much advantage for compile time. The next step is to split the compilation into separate steps. To do this, use -c option of gcc. This tells that you do not intend to generate the final executable immediately; rather gcc simply generates an .o file.
$gcc -Wall -c -o io.o io.c
$gcc -Wall -c -o init.o init.c
$gcc -Wall -c -o compute.o compute.c

To generate the final executable,
$gcc -o myprogram io.o init.o compute.o

Using Advanced gcc options:
===========================
1. Specifying search paths - When building a project, gcc has a default search path to use for things like include files and libraries. The opions for adding an entry to the include file search path and the library search path, respectively, are -I and -L. For instance, assume you have a program that wants to include a file named scsi.h. Your system may have this file under /usr/include/scsi, which is not on the default seach path. Therefore you might use:
$gcc -Wall -I/usr/include/scsi -o myprogram myprogram.c

If your program needs to linkt to the X11 library, for instance, you may need to inform the linker of the location of this library. You can do so by using:
$gcc -L/usr/X11R6/lih -Wall -o myprogram myprogram.c -lX11

2. The basic option to use to link in a library with your current program is -l (lower case L). For example to include mathlibrary which is simply named as m, the following command may be used:
$gcc -Wall -o mathprogram mathprogram.c -lm

3. All of the interactions between the various build programs are normally hidden from view. Their details are generally unimportant and distracting. However, one can request the details to be shown as gcc runs; to do so, use the -v option
$gcc -v -Wall -03 -o test2 test2.c

4. Specifying the -pipe option to gcc often can speed the compilation of your programs because temporary files are no longer necessary.
5. The gcc compiler and Linux environment both add numerous extensions to he language. By default, gcc also doesn't deal with a few undesirable aspects of ANSI C. You can tell gcc to disable ists extensions to ANSI C. This can be helpful if you wan to check to se if your programs will compile on other platforms. Also, some programs written for pure ANSI C may not compile with the GNU extensions. You can use the -ansi option to enable this type of behavior when compiling your programs. The -pendantic option disables even more GNU extensions and additions features. Additionally, it generates all warnings that theANSI C standard mandates, and programs that use nonstandard extensions won't compile.

[ Next Thread | Previous Thread | Next Message | Previous Message ]

[ Contact Forum Admin ]


Forum timezone: GMT-8
VF Version: 3.00b, ConfDB:
Before posting please read our privacy policy.
VoyForums(tm) is a Free Service from Voyager Info-Systems.
Copyright © 1998-2019 Voyager Info-Systems. All Rights Reserved.