Return to main page

GDB Tutorial: Finding Segmentation Faults

This tutorial will show you how to use gdb's up function to find the cause of segmentation faults. I'll be using a
c++ program I wrote as an example. The complete source code can be found here:

Here's the contents of mymovie.cpp, a program I wrote that uses "movie" objects. Each movie has a year (when it was
released) and a name (the title of the movie). In main, I create four movie pointers and store them in a list called
Pixar. Then I set the pointers to each point to their own movie objects. Finally, I use a for loop to iterate
through Pixar and print out the names of all the movies.

1	#include <iostream>
2	#include "movie.h"
3	using namespace std;
4
5	int main() {
6	  Movie* TheIncredibles = new Movie("The Incredibles", 2004);
7	  Movie* Up = new Movie("Up", 2009);
8	  Movie* Brave = new Movie("Brave", 2012);
9	  Movie* MonstersInc;
10	  Movie* Pixar[4] = {TheIncredibles, MonstersInc, Up, Brave};
11
12	  //print out the names of all the Pixar movies
13	  for (int i = 0; i < 4; i++){
14	    cout << Pixar[i]->getName() << endl;
15	    }
16
17	  return 0;
18	}
Let's compile the program. Remember that you should compile your program with -g if you want to use it with gdb.
$ g++ -g -c mymovies.cpp movie.cpp
$ g++ -g -o mymovies mymovies.o movie.o
So far, so good! Let's see what happens when I run it.
$ ./mymovies
The Incredibles
Segmentation fault (core dumped)
I'm getting a seg fault! I'm going to use gdb to figure out what happened.
$ gdb mymovies
I'm going to start off by just running my program in gdb and seeing what it tells me.
(gdb) run
Starting program: movieexample/mymovies
The Incredibles

Program received signal SIGSEGV, Segmentation fault.
0x4b801c86 in std::basic_string<char, std::char_traits<char>, std::allocator<char>
>::basic_string(std::string const) ()
   from /usr/lib/libstdc++.so.6
Missing separate debuginfos, use: debuginfo-install libgcc-4.6.3-2.fc16.i686 libstdc++-4.6.3-2.fc16.i686
I already knew that it seg faulted, but now gdb is telling me that the segmentation fault occurred at address 0x4b801c86 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const) (), which is in /usr/lib/libstdc++.so.6. This isn't in my program, so it doesn't seem very helpful! However, gdb has an "up" command that lets you go up a level in your program to the line where you called that function. I can safely assume that the basic_string function in std isn't the cause of our error. It's more likely that I passed it something that it's not meant to deal with. Let's look at what called this function:
(gdb) up
#1  0x08048cb9 in Movie::getName (this=0x804870d) at movie.cpp:18
18	  return name;
Okay, now we've got something we can work with! The getName() function must be calling the basic_string function with a strange argument, or arguments. Let's look at the getName() function: Here's the function call from Movie.h
  string getName();
And here's the function definition from Movie.cpp
string Movie::getName(){
  return name;
}
getName() should return name, a private member variable of Movie. That all looks fine! Let's look at what I'm passing to getName(). Gdb tells us that I'm passing it this=0x804870d. We can find more information about "this" by using gdb's print function.
(gdb) print this
$1 = (Movie * const) 0x804870d
Now we know we're passing it a movie pointer. Let's dereference the pointer to find out what it's pointing to.
(gdb) print *this
$2 = {year = 1527301251, name = }
No wonder getName() is having problems - there isn't a name for it to return! The value for year also doesn't make sense. It looks like a garbage value, the leftover values that variables store before you initialize them. Let's figure out where I'm passing this pointer to getName().
(gdb) up
#2  0x08048a97 in main () at mymovies.cpp:14
14	    cout << Pixar[i]->getName() << endl;
We've found the line where the segmentation fault occurs! Looking back at main(), we see that this line gets run more than once:
12	  //print out the names of all the Pixar movies
13	  for (int i = 0; i < 4; i++){
14	    cout << Pixar[i]->getName() << endl;
15	    }
I run getName() on all the movies in Pixar. Did I forget to initialize a member of Pixar? Looking back at main(), we can see that on line 9, a new pointer is created but it's not initialized.
9	  Movie* MonstersInc;
We've found our problem! I need to go back and initialize MonstersInc.