DEBUGGING GTK-GNUTELLA $Id: DEBUGGING 10291 2005-11-22 21:40:00Z rmanfredi $ 1. INTRO ======== This document gives some information on debugging gtk-gnutella and on finding potential bugs, focusing on the particulars of gtk-gnutella. 2. Using GDB on GTKG ==================== Using GDB on GTKG works fine in general, but there is one thing to keep in mind. The SIGPIPE signal is used within GTKG to determine if a connection was lost, so gdb should be instructed not to stop on this signal. (gdb) handle SIGPIPE nostop noprint 3. A short primer on memory allocation in GTKG ============================================== GTKG uses three different ways to allocate memory. malloc() is the most general way to allocate memory. It is actually used through the g_malloc() wrapper. That should be used in particular when you don't know or can't know the size of what is going to be freed, or to allocate long-lived memory that will stay around for the whole lifetime of the process. zalloc() is a zone allocator. This should only be used when you are planning to allocate and free many objects of the exact same size. You need a dedicated zone to allocate and free from, which is created through zget(). walloc() is a wrapper around zalloc(). It will call zalloc() on privately managed zones if the block is small, and use malloc() otherwise. To avoid memory fragmentation it is best to use walloc() whenever possible. You have to keep track of the allocated size to be able to give it back to wfree(). 4. Using GTKG-specific memory allocation tracking ================================================= GTKG comes with specific memory allocation tracking code which is not enabled by default. This code can be enabled by adding the right defines to CFLAGS. Make sure to do a 'make clean' after adding them so that all GTKG code is compiled with the same set of debugging instructions. Otherwise the debugging code will report weird results. The defines which can be used are: TRACK_MALLOC Track allocations made by malloc() and provide a report on memory not freed at the end of program execution. Memory freed twice is reported during program execution. TRACK_ZALLOC Track allocations made by zalloc() and provide a report on memory not freed at the end of program execution. Memory freed twice is reported during program execution. * note that there is no TRACK_WALLOC because walloc() is a wrapper around both malloc() and zalloc() so all memory allocation with walloc() will be caught with TRACK_MALLOC and either TRACK_ZALLOC or REMAP_ZALLOC. TRACK_ATOMS Track the allocation of Atoms used in GTKG. Some values, such as user agent strings, will be used multiple times in GTKG. GTKG uses Atoms for such values so that the actual string or value is only allocated once. Atoms with non-zero life counts are reported at the end of program execution. ZONE_SAFE This define allocates more memory when using zone allocations so that the used status can be tracked and double free's can be detected. ZONE_SAFE is automatically turned on when TRACK_ZALLOC is used. When tracking some additional memory is used to track the file and line information as well. REMAP_ZALLOC Cause both zalloc and walloc calls to actually use g_malloc. This has the benefit that g_malloc memory allocation tracking can be used for all memory allocations. This is useful if you want to use something like dmalloc to do memory allocation debugging. See http://dmalloc.com/ for more details. It does make much sense to use REMAP_ZALLOC together with the TRACK_* defines. MALLOC_STATS When supplied in addition to TRACK_MALLOC, and with REMAP_ZALLOC, this keeps track of allocation statistics during the lifetime of the program. * note: When compiling with MALLOC_STATS, it's best to use REMAP_ZALLOC as well since normally zalloc() has its own block tracking features that will not be accounted for in the malloc stats. Those statistics are dumped at the end of the program run, and also when a SIGUSR1 signal is sent. The SIGUSR2 signal resets the incremental statistics after dumping them and can be used to look at the memory usage variation between a SIGUSR2 and the next SIGUSR1 or SIGUSR2. During the execution of the program, statistics are sorted on the "incremental" counters whilst the final dump is sorted using the global counters. MALLOC_FRAMES If you have a GNU C library with the backtrace() call, this will keep track of the allocation stacks, free stacks and reallocation stacks and will show the various paths leading to a given call. This is still work in progress. At a later time, it will also be able to display stacks and related information.