gtk-gnutella logo
Current version: 1.1.13

Bug Report HOWTO

How do I file a useful bug report?

Developers love getting good bug reports. Unfortunately, for one reason or another, the reports they get are often of no use. Here's some hints on producing bug reports that will help make gtk-gnutella better. The ideal bug report would contain exactly the information needed - no more, no less - and a lovingly crafted patch to correct the problem. If you'd like to contribute a patch, please read the development page and the Developers Howto. Most of us, however, don't have the skills and/or time to fix gtk-gnutella for ourselves. That's OK, we can still help.

Keep in mind that the developers are only interested in bug reports from the latest released version or from versions built from current SVN. The developers code gtk-gnutella not for profit, but because they find it an interesting hobby and because they want to give something back to the open source community. Please don't treat them as if they were a company that you paid money to and that you can now expect service from. Supporting old versions falls into the "been there, done that, boring" category and new versions are generally better for you and better for the gnet.

A common mistake people make is to include too little information in their report. The developers would much rather search through a bug report and find what they need than to get no bug report at all. They don't have time to extract the information bit by bit from the user. So, if you're not sure, put it in. Once you have filed a report make sure you stay tuned for a request for more information from the developer. If they do ask you for more details, make sure you answer all their questions, even if the answer is "I don't know." Nothing is more frustrating than knowing you have a bug in your program but not having quite enough information to fix it.

The first thing developers want to know is the version of gtk-gnutella that experienced the bug so they will know which version of the source code has the problem (and if the bug is already fixed.) You can copy this information from the About pop up window. For example:

gtk-gnutella/0.92 (15/06/2003; X11; Linux 2.4.21 i586)

If it's a distribution package, say which one and where you got it. For example:

I'm using the GTK2-gtk-gnutella_0.92.0-0_i386.deb package from the gtk-gnutella web site.

If you compiled gtk-gnutella from SVN, you can use ident to verify which revisions of which sources files your binary was compiled with. This can be useful to verify whether you really compiled against the latest revision.

If you compiled it yourself, say which ./Configure options you used. For example:

./Configure -Dprefix=/usr -Dccflags="-g -Wall" -Doptimize="-O2" -Dgtkversion=2 -ders

Say what distribution and version and what architecture you're running. For example:

debian 2.2.22 on compaq alpha

Include the relevant version information in every bug report.

gtk-gnutella is doing something wrong or unexpected.

If gtk-gnutella is acting the way its programmers intended but you would prefer it behaved differently, then you should probably file a feature request rather than a bug report. Of course, there are exceptions - the behavior could be harmful in some unforeseen way or not conform to standards. Besides, it's hard to know what the developer intended, so the traditional confusion about bug vs feature is inevitable.

If you decide it is a bug, explain clearly what gtk-gnutella is doing wrong and what you think it should be doing. Your description should be detailed enough that someone else can reproduce the bug from your report. Which pane were you in and what options did you have selected? What were the precise actions that led to the bug? It may help to write a few quick notes before you forget.

gtk-gnutella won't compile!

Not many compilation problems are reported for gtk-gnutella. It's known to compile on Linux, OS X, and FreeBSD with gcc. If you have problems, paste the last compiler command, for example:

gcc -DHAVE_CONFIG_H -I. -I. -I.. -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include -I/usr/include/libxml2 -g -O2 -Wall -c nodes.c

and the errors that it generated into your report, along with the version and configuration options described above.

gtk-gnutella crashed! Now what?

In order to debug a crash, the executable needs to have its debugging symbols intact. Unfortunately, to save space on the hard drive and in memory, debugging symbols are stripped from gtk-gnutella when a distribution package is created. The rpm, debian, and slackware packages on the gtk-gnutella download site have all been stripped and are useless for debugging. But if you have a crash while using a package, you should still report the bug and the exact error message so others can attempt to reproduce it with an unstripped executable.

If you run gtk-gnutella from an xterm, then you'll find the error message in the terminal window (might have to scroll back a bit.) If you start gtk-gnutella from an icon or menu, then you can find the error wherever your X error log is. The whole error message and preferably about 10 lines leading up to the error should be pasted into your bug report. If you're paranoid (after all, they are out to get you) you could obfuscate filenames. You'll only find the error if gtk-gnutella aborts, not if it has a segmentation fault so you should say which case applies.

The most common reason for a gtk-gnutella crash is an "assertion" failure. Assertions are logical statements that are placed strategically throughout the code to help programmers find bugs. They "assert" that, at a particular place in the code execution, a particular condition must be met or the program is not behaving as the developer understands it should. For example, an assertion could state that a variable should at least have a value i.e., the value is not null: g_assert(header != NULL); or that the value should be in some numerical range: g_assert(parq_ul->position > 0);. If the assertion fails, the program aborts with an error message saying which assertion failed and exactly where in the code the assertion was placed. For example:

** ERROR **: file parq.c: line 1138 (parq_upload_free): assertion failed: (parq_ul->by_ip->uploading <= parq_ul->by_ip->total)

The developers can then investigate the values and hopefully realize where the bug is that led to the incorrect value. Or they can add more assertions further back in the code until the problem has been isolated. There are more than five hundred assertions in the gtk-gnutella code, so you can see why the developers need you to give them the exact error message, including the file and line number.

If you are using a package or you have stripped the gtk-gnutella executable yourself, there's not much more information to be gained from your crash unless you recompile and can reproduce the bug. If you don't want to do that, then provide the information described so far. That isn't usually enough information to fix the problem but at least it's a heads up that there is a bug. If you've provided a clear enough description, someone else may be able to reproduce the bug with a debugging version of gtk-gnutella.

If you have compiled gtk-gnutella yourself then by default, it will be compiled with the -O option passed to the compiler and, in addition make install will strip the executable. For bug reporting, you should compile with -g3 -O0 to get debugging symbols and use less optimization. For example:

./Configure -O -Dccflags="-g3 -Wall" -Doptimize="-O0" -ders

There is currently no way to tell make install to not strip the executable so you will have to copy the unstripped version over the installed version. For example:

su -c 'install -m 555 src/gtk-gnutella /usr/local/bin/gtk-gnutella'

When gtk-gnutella crashes, it will dump a "core" file containing an image of the memory it used, including all the values held in RAM at the time. This file can then be loaded into the gdb debugger to investigate the state of gtk-gnutella at the time of the crash. However, most distributions turn core dumps off by default. You can turn on core dumps with the shell command ulimit -S -c unlimited, which will only affect that terminal, or you can put the command on your shell config file (e.g., ~/.profile or ~/.cshrc) to allow core dumps globally. Newer core files will overwrite older ones so you should move them to a safe place. The core file will be in your home directory or in the current directory if you called gtk-gnutella from a terminal. If you're serious about bug hunting for gtk-gnutella you might want to use something like the following shell script to start it. You'll have to modify it to suit your system, of course. For instance, the core file could be named "core", "gtk-gnutella.core", "core.[PID]", etc.

#!/bin/sh

# This is where the configuration stuff is stored.
#export GTK_GNUTELLA_DIR=$HOME/.gtk gnutella

# Turn on core dumps and delete old dump and log
ulimit -S -c unlimited
rm -f core gtk-gnutella.log

# Run gtk-gnutella and redirect output to a log file
# The log could get quite large if your uptime is long.
# To just keep output in the terminal use:
# gtk-gnutella
# instead and remove the other log references.
gtk-gnutella >gtk-gnutella.log 2>&1

# If a core is dumped, create a uniquely named directory
# to save the core, log and executable
if [ -e core ] ; then
  Core_Save_Dir=$(date "+core%Y.%m.%d.%H.%M.%S")
  mkdir $Core_Save_Dir
  cp $(which gtk-gnutella) $Core_Save_Dir
  cp core $Core_Save_Dir
  cp gtk-gnutella.log $Core_Save_Dir
fi

Ok, now that you have an unstripped executable and a core file, you can use the gdb debugger to make a backtrace. Note that in this example, the gtk-gnutella executable and the core have been saved to the same directory.

~/src/test/core2003.06.12.18.01.40> gdb -c core ./gtk-gnutella
GNU gdb 5.2
Copyright 2002 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-slackware-linux"...
Core was generated by `gtk-gnutella'.
Program terminated with signal 6, Aborted.
Reading symbols from /usr/lib/libgtk-1.2.so.0...done.
Loaded symbols for /usr/lib/libgtk-1.2.so.0
Reading symbols from /usr/lib/libgdk-1.2.so.0...done.
Loaded symbols for /usr/lib/libgdk-1.2.so.0
Reading symbols from /usr/lib/libgmodule-1.2.so.0...done.
Loaded symbols for /usr/lib/libgmodule-1.2.so.0
Reading symbols from /usr/lib/libglib-1.2.so.0...done.
Loaded symbols for /usr/lib/libglib-1.2.so.0
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /usr/X11R6/lib/libXext.so.6...done.
Loaded symbols for /usr/X11R6/lib/libXext.so.6
Reading symbols from /usr/X11R6/lib/libX11.so.6...done.
Loaded symbols for /usr/X11R6/lib/libX11.so.6
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /usr/lib/libz.so.1...done.
Loaded symbols for /usr/lib/libz.so.1
Reading symbols from /usr/lib/libxml2.so.2...done.
Loaded symbols for /usr/lib/libxml2.so.2
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /usr/X11R6/lib/X11/locale/common/xlcDef.so.2...done.
Loaded symbols for /usr/X11R6/lib/X11/locale/common/xlcDef.so.2
Reading symbols from /usr/X11R6/lib/X11/locale/common/ximcp.so.2...done.
Loaded symbols for /usr/X11R6/lib/X11/locale/common/ximcp.so.2
Reading symbols from /lib/libnss_compat.so.2...done.
Loaded symbols for /lib/libnss_compat.so.2
Reading symbols from /lib/libnsl.so.1...done.
Loaded symbols for /lib/libnsl.so.1
Reading symbols from /lib/libnss_db.so.2...done.
Loaded symbols for /lib/libnss_db.so.2
Reading symbols from /lib/libnss_files.so.2...done.
Loaded symbols for /lib/libnss_files.so.2
Reading symbols from /lib/libdb-3.1.so...done.
Loaded symbols for /lib/libdb-3.1.so
#0 0x4036b2f1 in kill () from /lib/libc.so.6
(gdb)

OK, now let's do a full backtrace:

(gdb) bt full
#0 0x4036b2f1 in kill () from /lib/libc.so.6
No symbol table info available.
#1 0x4036afbc in raise () from /lib/libc.so.6
No symbol table info available.
#2 0x4036c7cb in abort () from /lib/libc.so.6
No symbol table info available.
#3 0x4018f9de in g_logv () from /usr/lib/libglib-1.2.so.0
No symbol table info available.
#4 0x4018fa91 in g_log () from /usr/lib/libglib-1.2.so.0
No symbol table info available.
#5 0x0814efda in parq_upload_free (parq_ul=0x8d62328) at parq.c:1138
No locals.
#6 0x0814d696 in parq_close () at parq.c:416
        queues = (GList *) 0x0
        dl = (GList *) 0x0
        sl = (GSList *) 0x8a20040
        remove = (GSList *) 0x8a204b8
        removeq = (GSList *) 0x8a204c0
#7 0x0811f3a4 in gtk_gnutella_exit (n=0) at main.c:113
        now = 1055466099
        tick = 143511256
#8 0x080d7eba in quit (force=0) at main_cb.c:44
        confirm = 0
#9 0x080d7f04 in on_button_quit_clicked (button=0x8358d44, user_data=0x0) at main_cb.c:62
No locals.
#10 0x400b10d5 in gtk_marshal_NONE__NONE () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#11 0x400e091c in gtk_signal_remove_emission_hook () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#12 0x400dfd85 in gtk_signal_set_funcs () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#13 0x400dde63 in gtk_signal_emit () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#14 0x401149be in gtk_widget_activate () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#15 0x400b9534 in gtk_menu_shell_activate_item () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#16 0x400b87ba in gtk_menu_shell_deactivate () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#17 0x400b0d5f in gtk_marshal_BOOL__POINTER () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#18 0x400dfdc3 in gtk_signal_set_funcs () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#19 0x400dde63 in gtk_signal_emit () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#20 0x4011487b in gtk_widget_event () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#21 0x400b0ca5 in gtk_propagate_event () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#22 0x400afe0e in gtk_main_do_event () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#23 0x4015f047 in gdk_wm_protocols_filter () from /usr/lib/libgdk-1.2.so.0
No symbol table info available.
#24 0x4018d258 in g_main_dispatch () from /usr/lib/libglib-1.2.so.0
No symbol table info available.
#25 0x4018d863 in g_main_iterate () from /usr/lib/libglib-1.2.so.0
No symbol table info available.
#26 0x4018d9fc in g_main_run () from /usr/lib/libglib-1.2.so.0
No symbol table info available.
#27 0x400af707 in gtk_main () from /usr/lib/libgtk-1.2.so.0
No symbol table info available.
#28 0x080d7cf2 in main_gui_run () at main_gui.c:650
        coord = {0, 0, 1276, 965}
#29 0x0811fc2b in main (argc=1, argv=0xbffff924, env=0xbffff92c) at main.c:463
        i = 256
#30 0x4035a17d in __libc_start_main () from /lib/libc.so.6
No symbol table info available.

Paste the backtrace into your bug report.

The developers will probably need some more information but if you send the backtrace and the other information, then they'll have a good place to start. They can then get back to you and request that you load the core into gdb again and print the specific values they need. However, for bonus points, you can anticipate their needs. If you understand C, you can take a peek at the code and decide what to include but if you don't know C, you can still take a guess by having a look at the assertion. In this example, the error message was:

** ERROR **: file parq.c: line 1138 (parq_upload_free): assertion failed: (parq_ul->by_ip->uploading <= parq_ul->by_ip->total)

Looking at the backtrace, you see in #5 parq.c:1138, the same line where the assertion was placed, so lets investigate some values in that frame:

(gdb) frame 5
#5 0x0814efda in parq_upload_free (parq_ul=0x8d62328) at parq.c:1138
1138          g_assert(parq_ul->by_ip->uploading <= parq_ul->by_ip->total);

First, lets print out the values of the members of parq_ul.

(gdb) p * parq_ul
$1 = {magic = 1782120609, flags = 10, position = 1735, relative_position = 1, has_slot = 0, had_slot = 0, eta = 81,
  expire = 1055465788, retry = 1055465787, enter = 1055465787, updated = 1055465787, ban_timeout = 1055466387,
  disc_timeout = 0, last_queue_sent = 0, queue_sent = 0, queue_refused = 0, is_alive = 0,
  id = 0x8a15af8 "6cad90dc1f0edd94f5d0e991cc89f25e",
  ip_and_name = 0x8a16578 "3521280541 Somethingorother.mp3",
  name = 0x8a16583 "Somethingorother.mp3", remote_ip = 3521280541, file_size = 2652639,
  chunk_size = 1005329, ip = 0, port = 0, major = 0, minor = 0, queue = 0x84f85c8, by_ip = 0x86259e8}

Notice that the last member listed is by_ip = 0x86259e8. The assertion compares two of the members of parq_ul->by_ip so let's print out the values.

(gdb) p * parq_ul->by_ip
$2 = {uploading = 2, total = 1, ip = 3521280551, list = 0x8bb639c}

There are the values the developer was looking for: parq_ul->by_ip->uploading = 2 and parq_ul->by_ip->total = 1. Since 2 <= 1 is false, the assertion failed. Now the developer can try and figure out what went wrong.

Where's the best place to submit my bug report?

You can report your bug using the SourceForge.net Bug Tracker or you can email your report to the gtk-gnutella-devel mailing list. You can also find a developer on IRC on the Freenode network in the #gtk-gnutella channel.

IRC can be useful for a quick response if you happen to catch a developer in the channel, but it's easy for bugs to be forgotten if they are only reported there. It can be a good place to go if you aren't sure whether your problem is really a bug or not. It's an excellent place to go when you have already made a report on the list or bug tracker and you want to know if the developers need more information from you. At the time this was written, the developers all lived in the Central European Time (CET) zone (UTC+1). You might catch them for a quick question in the morning before work but the best time is in the evenings or on weekends. You can have a look at the IRC log to get an idea of when to find people in the channel. The times listed in the log are also UTC+1.

The developers' mailing list is a good place to report critical bugs like crashes, although you could use the bug tracker for these as well. More people will read a bug report on the list than on the bug tracker and it's perhaps a little more convenient for reading backtraces, etc. On the other hand, bugs reported to the list can be more easily forgotten than those submitted to the bug tracker. You have to register on SourceForge to subscribe to gtk-gnutella-devel, but you don't need to be subscribed to post a message. If you post a message although you're not subscribed to the mailing list, either add your own email address to the Reply-To: header or mention that you're not subscribed.

The best place to submit bugs is the SourceForge bug tracker. After all, that's what it was designed for. Have a look and see if your bug has already been reported and if so, add your report as a comment rather than submitting a new bug. You need to register at SourceForge and be logged in before you can submit a bug.

Once you have submitted your report, don't forget it. Your bug report is not complete until you've answered any follow-up questions the developers have for you. Bug reporters who don't respond to followups are a major irritant to developers. Debugging software can be a frustrating experience for developers but receiving good bug reports can help make writing free software a little more satisfying.

SourceForge.net Logo   Glade   RSS Feed Available   Ohloh Metrics   Coverity Scan Build Status   gtk-gnutella at GitHub  
gtk-gnutella © 2000-2014 by Yann Grossel, Raphaël Manfredi and various contributors.