What is a backtrace?

So Gaim crashed on you again, huh? I'm sorry to hear that. Maybe you can help prevent it from happening again. To diagnose the problem, we need to know the last few functions that were called before Gaim crashed. This output is called a "backtrace."

The Easy Way

If you are able to reproduce the crash, the easiest way to obtain a backtrace is by doing the following:

[mark@diverge mark]$ gdb gaim
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 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 "i386-redhat-linux-gnu"...
(no debugging symbols found)...
(gdb) handle SIGPIPE nostop
(gdb) run
(stuff scrolls by)
(do whatever it is you did to get Gaim to crash)
(gdb) bt full
(the bt scrolls by)
(copy and paste all of this to your bug report)
(gdb) quit
[mark@diverge mark]$

The Hard Way

or "How To Make Use Of A Core File"

When a program crashes it typically leaves a core file behind. In a console window when you run ls, you should see a file called core:

~ $ ls
core

Sometimes this file is also called gaim.core or something similar, depending on what OS you use and what your settings are. If you don't see this file, it's possible that it's in a different location, and you should look at the settings for your OS to see where it might be. It's also possible that the core file was not created at all; this would happen if your system was configured not to leave a core file. Often you just need to tell your shell to not restrict the size of core files (this may only work for bash):

~ $ ulimit -c unlimited

If you have a core file, first check to make sure that it was created by gaim, by using file to examine it:

~ $ file core
core: ELF 32-bit LSB core file of 'gaim' (signal 11), Intel 80386, version 1, from 'gaim'

The output of file may look different depending on your OS and hardware, but it should still be apparent that it was created by gaim.

Now that you have the core file, you'll want to get the useful information out of it. In order to do that, you'll have to open it in GDB. GDB stands for GNU DeBugger, and is a very useful programmer's tool. It needs to know which application created the core file and what the core file name is, so run:

~ $ gdb gaim core

If you use the applet version of gaim, you should use gaim_applet instead of gaim when running gdb. You don't have to give the full path to the gaim/gaim_applet binary as long as it is in your PATH environment variable (i.e. if you can run gaim and have it work, you don't need the full path). You do, however, have to specify the correct name of the core file. At this point, gdb should start printing information about what it's doing:

GNU gdb 5.0
Copyright 2000 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 "i686-pc-linux-gnu"...
Core was generated by `gaim'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libesd.so.0...done.
Loaded symbols for /usr/lib/libesd.so.0
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6

And so forth. There are a couple reasons why you might see something other than this. One reason is if gdb can't find something it needs, it might give a warning such as "No such file or directory.", in which case you may have to give the full path to both gaim and the core file. Another reason would be if the core file isn't created by gaim, you may see a message saying "warning: core file may not match specified executable file."

If gdb loaded gaim and the core file successfully, then once it's done loading all the symbols that it will need, it should print the information from the top of the stack, and prompt you:

#0  0x404f1140 in poll () from /lib/libc.so.6
(gdb)

Now you'll want to get the backtrace. At the prompt, type either backtrace or bt. gdb should then print a list of all the functions that were called leading up to the crash:

(gdb) backtrace
#0  0x404f1140 in poll () from /lib/libc.so.6
#1  0x40325f99 in g_main_poll (timeout=-1, use_priority=0, priority=0) at gmain.c:1034
#2  0x4032594d in g_main_iterate (block=1, dispatch=1) at gmain.c:808
#3  0x40325cfc in g_main_run (loop=0x81becb0) at gmain.c:935
#4  0x4023b4b7 in gtk_main () at gtkmain.c:524
#5  0x805b131 in main (argc=1, argv=0xbffffa94) at aim.c:669
#6  0x4044938b in __libc_start_main () from /lib/libc.so.6
(gdb)

When you get the backtrace, instead of seeing function names, you might see '??' instead. If that's the case, gdb couldn't read the function names from gaim and the core file, and so the core file won't end up being very useful after all. However, if you were able to see the function names, then copy all of the output from the backtrace and post a bug report. Be sure to also indicate what you were doing at the time.

Now you can exit gdb by typing quit:

(gdb) quit
~ $

There may be other useful information that can be retrieved from the core file, such as the values of variables. For this reason it's a good idea to keep the core file. If you upgrade Gaim, the core file will no longer match the binary, and it won't be useful anymore; however, don't let that stop you from upgrading Gaim, since there's a good chance your bug will have been fixed.

Distribution Notes

Additional notes for those who want to do more

Often, you will see a backtrace where one or more of the top lines is in malloc() or g_malloc(). When this happens, chances are your backtrace isn't very useful. The easiest way to find some useful information is to set the environment variable MALLOC_CHECK_ to a value of 2. In bash this would be

export MALLOC_CHECK_=2

You can re-run gaim inside gdb to get a new backtrace. Note, this does not affect existing core files.