Kickass banner graphics by Jeremy Mikola.
 .corporate News
Contact Us
F.A.Q.
Terms of Service
 .random .stuff !LiveJournal X
Borrow System
Document(s)
Hang Exmoure
My .OMLETTE
WebChat   (0 users.)
 .erf
Deterministic Quotes
Evil Adam Quotes

Submit a Quote   (0 pending.)
 .WTF * == Source updated recently.
X == Data updated recently.

omlettesoft.com is Copyright © 2013 Lord Omlette.

everything I know about gdb

by Lord Omlette.
Created 2006-07-17 175 BMT.
Updated 2006-07-17 208 BMT.

gdb is the GNU standard debugger. This used to be the tutorial I wrote for the CS 384 class I was the TA for... Now I use it as a self-reference.

The most important thing to remember when using gdb is to compile w/ the -g option. -g will insert debugging information into your executable, so the debugger will know what goes where. (It helps to have one terminal open w/ the source that you're editing and another terminal open w/ the debugger, I guess?)

Not let's assume you just compiled a program w/ the -g option and you have an executable, a.out. Fire up gdb like so:

gdb a.out

You'll be given some copyright information, and then you'll see the prompt:

(gdb)

For this exercise, you'll start by typing break main and then hit return. You'll get a message back:

Breakpoint # at MEMORYADDRESS: file FILENAME, line LINENO.

Pay attention to the number! Too late, you already forgot. ;_; Type info break to see which breakpoints you have set. No problem. Now type run and hit enter. The program will start running and blow past the standard runtime's initialization, which is boring as all hell if you aren't turned on by that sort of thing. Once the execution hits the main function, you'll see something like:

Breakpoint 2, main (argc=1, argv=0xbfbffa88) at test.cpp:16
16		Data * head = new Data(0);

The 16 at the start of the 2nd line indicates that this is line #16 located in test.cpp. This line is the next line slated for execution. Now we have 2 choices: we can step over the function (remember: the constructor is a function call, sort of), or we can step into the function to see how it operates. Type step then hit enter. It'll spit out some stuff like:

Data (this=0x804b030, value=0) at test.cpp:7
6		std::cout << "Constructor!" << std::endl;

Remember what I said last time about this being an implicit pointer to each member of a class? You can see the this pointer getting passed to the constructor right here. Now we're on line 6 of test.cpp, which happens to be the first line in Data's default constructor. If you don't type anything but just hit return, gdb will execute the last command you typed. So you can keep stepping through lines of code. Where are we? Did you forget already? You can type backtrace to see where on the program stack you are. Try it, if you're still in the constructor, you'll see something like:

#0  Data (this=0x804b030, value=0) at test.cpp:7
#1  0x08048b4d in main (argc=1, argv=0xbfbffa88) at test.cpp:16
#2  0x080488c2 in ___start ()

Now type info locals and hit return. You should get a message that says No locals. Wow, the debugger is right, there are no local variables in this function! What about in main? We don't want to leave the constructor just yet though. So let's move inside the stack. The lowest frame of the stack is what's currently being executed, so let's move up. Type up and hit enter. Then type info locals again and hit enter. gdb will tell you all about the two variables local to the main function, head and current. But there are arguments passed to main! Type info args and hit enter, you should see the values of argc and argv. Hm, it seems the value displayed for argv is fairly useless. We know it's an array, so let's look inside it. Type print argv[0] and hit enter. You'll see the value of argv[0]! gdb can understand basic C/C++ expressions, so you really should experiment with the print command. (Note, head is still being constructed, so you don't want to look inside that.) To return to the constructor from where you should be if you've been following along, you have to get to frame 0 from frame 1, so type down and hit enter.

When you're done stepping through, type continue and hit return, and gdb will revert to executing the program at full speed, unless it hits a breakpoint or it needs user input or the program ends or something else happens. You get the idea. Now type info by itself and hit return. There are lots and lots of options for you to play with. So please play with it, and hopefully this will make the rest of your homework easier...

If you're in the middle of running a program, and you ever want to stop, then use kill to terminate the process being debugged, and use quit to exit gdb.

Listing 1 - test.cpp

This is the horribly bad sample program that I started out w/ in recitation... If you can think of a better sample program to use, I'm all ears.

#include <iostream>

class Data {
public:
	Data (int value) {
		std::cout << "Constructor!" << std::endl;
		next = NULL;
		this->value = value;
	}

	Data * next;
	int value;
};

int main (int argc, char * argv[]) {
	Data * head = new Data(0);
	Data * current = head;

	//allocate a list
	for (int i = 1; i < 4; ++i) {
		current->next = new Data(i);
		current = current->next;
	}

	delete head;
	return 0;
}

"everything I know about gdb" is Copyright © 2006 Lord Omlette. If you know otherwise, hollar.

Printable Version



quote #943:

Cutting the space budget really restores my faith in humanity. It eliminates dreams, goals, and ideals and lets us get straight to the business of hate, debauchery, and self-annihilation.
-Johnny Hart
  -added 2002-11-02