2 Uncommon Linux Certifications
Being Sysadmin, the Root User in SUSE Linux 9.3
Linux: The GNU General Public License

Find Bugs in Linux by Using gdb

To understand how you can find bugs in Linux by using gdb, you need to see an example. The procedure is easiest to show with a simple example, so the following, dbgtst.c, is a contrived program that contains a typical bug.

#include <stdio.h>
static char buf[256];
void read_input(char *s);
int main(void)
{
char *input = NULL; /* Just a pointer, no storage for string */
read_input(input);
/* Process command. */
printf("You typed: %s\n", input);
/* . . ._*/
return 0;
}
void read_input(char *s)
{
printf("Command: ");
gets(s);
}

This program’s main function calls the read_input function to get a line of input from the user. The read_input function expects a character array in which it returns what the user types. In this example, however, main calls read_input with an uninitialized pointer — that’s the bug in this simple program.

Build the program by using gcc with the -g option:

gcc -g -o dbgtst dbgtst.c

Ignore the warning message about the gets function being dangerous; you’re trying to use the shortcoming of that function to see how you can use gdb to track down errors.

To see the problem with this program, run it and type test at the Command: prompt:

./dbgtst
Command: test
Segmentation fault

The program dies after displaying the Segmentation fault message. For such a small program as this one, you can probably find the cause by examining the source code. In a real-world application, however, you may not immediately know what causes the error. That’s when you have to use gdb to find the cause of the problem.

To use gdb to locate a bug, follow these steps:

  1. Load the program under gdb.

    For example, type gdb dbgtst to load a program named dbgtst in gdb.

  2. Start executing the program under gdb by typing the run command. When the program prompts for input, type some input text.

    The program fails as it did previously. Here’s what happens with the dbgtst program:

    (gdb) run
    Starting program: /home/edulaney/swdev/dbgtst
    Command: test
    Program received signal SIGSEGV, Segmentation fault.
    0x400802b6 in gets () from /lib/tls/libc.so.6
    (gdb)
  3. Use the where command to determine where the program died.

    For the dbgtst program, this command yields this output:

    (gdb) where
    #0 0x400802b6 in gets () from /lib/tls/libc.so.6
    #1 0x08048474 in read_input (s=0x0) at dbgtst.c:16
    #2 0x08048436 in main () at dbgtst.c:7
    (gdb)

    The output shows the sequence of function calls. Function call #0 — the most recent one — is to the gets C library function. The gets call originates in the read_input function (at line 16 of the file dbgtst.c), which in turn is called from the main function at line 7 of the dbgtst.c file.

  4. Use the list command to inspect the lines of suspect source code.

    In dbgtst, you may start with line 16 of dbgtst.c file, as follows:

    (gdb) list dbgtst.c:16
    11 return 0;
    12 }
    13 void read_input(char *s)
    14 {
    15 printf("Command: ");
    16 gets(s);
    17 }
    18
    (gdb)

    After looking at this listing, you can tell that the problem may be the way read_input is called. Then you list the lines around line 7 in dbgtst.c (where the read_input call originates):

    (gdb) list dbgtst.c:7
    2 static char buf[256];
    3 void read_input(char *s);
    4 int main(void)
    5 {
    6 char *input = NULL; /* Just a pointer, no storage for string */
    7 read_input(input);
    8 /* Process command. */
    9 printf("You typed: %s\n", input);
    10 /* . . . */
    11 return 0;
    (gdb)

    At this point, you can narrow the problem to the variable named input. That variable is an array, not a NULL (which means zero) pointer.

  • Add a Comment
  • Print
  • Share
blog comments powered by Disqus
The GNU Debugger
An Overview of Linux Programming
Linux: The GNU makefile
Linux: Shells, Scripting, and Data Management
Linux Security Tools
Advertisement

Inside Dummies.com