LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Articles > Technical
User Name
Password

Notices


By Matir at 2006-07-24 15:47
The GNU Debugger (GDB for short) is a powerful tool in the debugging of programs written in C, C++, and many other languages. This article will cover an introduction to debugging C applications using GDB.

Compiling programs for debugging
First off, you want to compile programs with a couple of extra options to ease debugging. I generally like '-g -Wall' when compiling programs. The -g tells gcc to add debugging symbols into the compiled binaries and the -Wall activates all compile time warnings, which, if you pay attention to them, can save you the trouble of ever needing the debugger.

First program
Our first program will simply copy a string and print it out. Seems easy enough, right? The code for this program (ex1.c) is:
Code:
#include <stdio.h>
#include <string.h>

int main(int argc,char **argv){
        char *out;
        char *in = "This is some text";

        strcpy(out,in);

        printf("Text: %s\n",out);
}
Experienced programmers may have already noticed the two (intentional) bugs in this code. But let's use our tools to find them. First, we compile the program:
Code:
$ gcc -g -Wall -o ex1 ex1.c
ex1.c: In function ‘main’:
ex1.c:11: warning: control reaches end of non-void function
GCC's warned us that we didn't place a return statement in our code. Fixing this by adding "return 0;" after the printf statement gives us no more warnings, so we try to run our program:
Code:
$ ./ex1
Segmentation fault
Hrrm, hardly what we expected. Let's see if we can spot the source using gdb.

Running a program with gdb.
To run our program with gdb, we just run 'gdb ./ex1' and then we are presented with the gdb prompt. Typing 'run' and pressing enter at this prompt will allow us to start the program in the debugger.
Code:
$ gdb ./ex1
GNU gdb 6.4-debian
Copyright 2005 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 "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".

(gdb) run
Starting program: /home/david/projects/gdb/ex1

Program received signal SIGSEGV, Segmentation fault.
0xb7e8cda6 in strcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb)
Now we know that the program called a strcpy somewhere and subsequently crashed. But we probably want to know exactly what line it was on: in any more complicated program, there might be hundreds of calls to strcpy. So we ask gdb for what's called a 'backtrace': a listing of all the functions called by our program and the libraries it's using. We can then use 'up' to move up through the backtrace until we get to our own code.
Code:
(gdb) backtrace
#0  0xb7e8cda6 in strcpy () from /lib/tls/i686/cmov/libc.so.6
#1  0x080483cd in main (argc=1, argv=0xbf9783b4) at ex1.c:8
(gdb) up
#1  0x080483cd in main (argc=1, argv=0xbf9783b4) at ex1.c:8
8               strcpy(out,in);
(gdb)
This tells us that it was on line 8 for ex1.c when the program crashed. But even knowing that, we don't know why it happened. Let's see what gdb can tell us about the variables 'in' and 'out'.
Code:
(gdb) print in
$1 = 0x80484d8 "This is some text"
(gdb) print out
$2 = 0x0
Here we see that while in contains the text we expect, out is set to 0x0 or "NULL". You can use 'quit' or press ^D to exit gdb now. Looking back at our original source, we can see that we never allocated memory for 'out'. We can fix that just by allocating a character array for the destination.
Code:
#include <stdio.h>
#include <string.h>

int main(int argc,char **argv){
    char out[100];
    char *in = "This is some text";

    strcpy(out,in);

    printf("Text: %s\n",out);
    return 0;
}
After we compile again, we'll run it and see our results:
Code:
$ ./ex1
Text: This is some text
Exactly what we expected. In the next part, I'll cover the use of breakpoints and examine new ways to look at the memory space of your application. Any feedback is of course appreciated and will help shape the future contents of these articles.

by Nylex on Fri, 2006-07-28 10:43
Thanks. I've never used gdb before (and it looked scary), so that was a nice introduction . It might just be me, but the "#include" lines don't look complete. Shouldn't they read something like "#include <foobar.h>"? At first I thought that was intentional, but if it was, it wasn't picked up by gcc or gdb. Did I miss something?

by BHABANIPRASADPATI on Mon, 2009-07-20 07:17
its not working in Solaris .
man gcc
&
man gdb
are giving absolutely no output -> no manul entry found.

by masterniks on Fri, 2011-10-21 09:46
AH...a helpul intro to gdb...!!

by P.G.Krish on Wed, 2016-11-09 23:33
Hi,
I didn't get segmentation fault, even iam not put any
Code:
return 0
.Its giving same output to me


  



All times are GMT -5. The time now is 09:28 AM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration