GDB Core Dump Files

What’s a Core Dump?

It’s a file created when your program terminates abnormally. It contains a snapshot of the program’s state at the time of the failure.

What does it look like?

On Linux it will appear in the same location as the executable and will be named something like:

core.4196

Where the number is the process id of the program while it was running.

And what can I do with it?

You can have a look at it using GDB! GDB can read a core file to give you valuable information about a crash after the event.

Some Linux distributions have the ability to create core files disabled by default – you need to type:

ulimit -c unlimited

before running the program to allow the creation of the core file when the program terminates.

To examine a core file, just pass it to gdb:

gdb core.324

GDB will load up all the info and it will look as though you have just run the program and seen the error. You’ll be able to view a backtrace and a range of other information, but it will be a frozen “snapshot” of execution.

Instant debugging!

GDB Init Files Save Time At Startup

I can’t leave the subject of GDB alone for too long, so today I thought I’d talk about GDB init files.

Each time GDB is run, it checks first your home directory and then the current directory for the existence of a file called .gdbinit. If it finds this file, it reads the contents and runs any commands it finds there.

Note: as of version 7.5 GDB needs permission to load files from anywhere other than your home directory. See this update for further details.

This is extremely handy if you are repeatedly debugging an executable and don’t want to keep typing in the same old commands at startup.

For example, if you always put a breakpoint in a certain method because you like it as a starting point, you can specify this in the .gdbinit file, exactly as you would on the command line for GDB:

b main

And if you just can’t be bothered to keep typing ‘r’ to run GDB once it’s loaded your program, you can specify that too:

b main
r

You can also add any arguments that you repeatedly type in:

set args param1 param2
b main
r

And any configuration settings that you might want:

set prompt debug-->
set args param1 param2
b main
r

Now all you have to do is run GDB on your exe as usual, but now it will set up a custom prompt, pass in your arguments, set a breakpoint in main, and even start the program for you.

Next thing you know, you’ve got a GDB prompt at the top of the main function and you’re ready to go!

GDB Conditional Breakpoints

Last week we looked at setting breakpoints in GDB. All well and good.

But what if you have a large loop running and you only want to look at what’s happening as it nears the end? Do you really have to step through 99 iterations in a 100 item loop?

Of course you don’t. Step forward the conditional breakpoint.

Set a conditional breakpoint using a condition

In GDB you can specify a condition in the programming language you are debugging and apply it to any breakpoint. Let’s stop a loop at the 99th iteration (I’m debugging C/C++, so my conditions are written in C/C++):

(gdb) b Message.cpp:112 if i == 99

That’s all there is to it.

To ensure gdb stops execution, use the first line of code inside the loop as the stopping point, not the loop itself.

You can also specify a condition on an existing breakpoint by using the breakpoint number as a reference:

(gdb) cond 3 i == 99

And remove a condition from a breakpoint using:

(gdb) cond 3
Breakpoint 3 now unconditional.

That’s great! What else can you do?

Pretty much anything you like! Just write the condition exactly as if you were testing for it in your code, e.g.:

(gdb) cond 1 strcmp(message,"earthquake") == 0
//stop if the array message is equal to 'earthquake'
(gdb) cond 2 *p == 'r'
//stop if the char* pointer p points to the letter 'r'
(gdb) cond 3 num < 0.75
//stop while the float num is less than 0.75

Conditional breakpoints covered and your efficiency increased, all in less than 5 minutes!

GDB Breakpoints

Today we’re going to take a quick look at the humble breakpoint in GDB.

You can set a breakpoint:

  • before you run the program in GDB
  • if you interrupt GDB with CTRL-C

Positioning your breakpoints

Set a breakpoint using the handy shortcut ‘b’ followed by the location. There are lots of ways to specify the location, but the most common are:

(gdb) b MessageSender.cpp:118

Pattern: filename:linenumber. Nice and simple. Puts a breakpoint at line 118 in the file MessageSender.cpp

(gdb) b 267

Pattern: linenumber. Puts a breakpoint at line 267 in the current source file. If execution has not started, the breakpoint will be inserted in the main program file.

(gdb) b main

Pattern: functionname. Puts a breakpoint at the beginning of the named function. For C++  class methods, see below.

(gdb) b Message::sendMessage

Pattern: classname::method. Puts a breakpoint at the beginning of the named method. Use tab after the :: to display a list of available methods.

(gdb) b MessageParser.c:getLen

Pattern: filename:function. Puts a breakpoint at the beginning of the named function in the file specified (useful if there is any ambiguity caused by functions with the same name).

Viewing and deleting breakpoints

To see all your breakpoints in a numbered list, type:

(gdb) i b

Delete them all with:

(gdb) d

Or specifically with the breakpoint number from the list:

(gdb) d 4

Preserve your breakpoints

Don’t quit GDB. Just type CTRL-C and then ‘r’ (for run). This will restart your program from the beginning, leaving all your breakpoints intact. Lovely!