GLib RFC: Improve checking provided with --enable-mem-check

Ben Stanley bds02@uow.edu.au
Thu, 07 Jun 2001 18:24:10 +1000


Thanks for all the replies.

I am now planning to maintain a separation between all the hash table 
data and the user block areas, to increase robustness in the face of 
rogue programs.

I looked at the pluggable interface in glib 1.3.5. It seems that the 
g_malloc/g_free etc functions must be installed by the program at the 
beginning of main, before initialising glib etc. However, I wish to 
support installing the debugging memory manager into a previously 
compiled program. This is already possible by compiling glib 1.2.x with 
--enable-mem-check and installing it into a non-standard location (or 
with a non-standard name), and then using

export LD_PRELOAD=/opt/lib/libglibdebug.so

(LD_PRELOAD is documented on the ld.so man page) to replace all the glib 
functions in a dynamically linked executable as it loads. A similar 
effect may be achieved from inside gdb by using

set environment LD_PRELOAD=/opt/lib/libglibdebug.so

Thus, the debugging memory manager may be used optionally at run-time 
just by setting an environment variable, even with the existing versions 
of glib.

I am planning to supply the replacement memory interface functions 
(g_malloc, g_free, g_realloc etc) in a library called libgmemdebug.so. 
This will support the above usage pattern. If you wish to compile a 
debugging version of your program with the debugging memory manager 
built in, then it would be possible to link against this library before 
linking against libglib.so in order to override the memory allocation 
functions. I see little need for the pluggable memory interface in glib 
1.3...

However, the pluggable memory interface may be supported by exporting my 
debugging memory manager interface as

g_debug_malloc()
g_debug_free()
g_debug_realloc()
etc

and also supplying a utility function to facilitate initialising the 
struct of function pointers to do the right thing wrt the debugging 
memory manager. This would require a separate library containing the 
different names... I am not as keen on this option.

I am also going to have to export some new functions to make available 
the debugging aspects of the memory manager to user programs. It is 
envisaged that this functionality would only be used by debugging 
versions of applications, not release versions. So I will have to supply 
a separate header file.

So it seems now that my design should be separated from glib itself, so 
as to build a separate library which may be optionally linked or 
run-time pre-loaded to obtain debugging functionality, without 
re-compiling glib itself.

Another question: Is it possible to programmatically obtain the current 
stack trace? This feature would be very useful for tracking down leaks. 
Whenever g_malloc is called, the stack trace could be obtained and 
stored with the block information. When leaks are reported, the stack 
trace is printed out for each block. This should allow the source of 
leaks to be pinpointed quickly and accurately. Of course, it would 
vastly increase run-time overhead, and so should be able to be turned on 
and off. I would suggest that a global variable be made available, to be 
turned on through an environment variable, by setting in the debugger, 
or programmatically through the debugging interface.

How do people feel about run-time overhead? Is it worth incorporating 
more checks, at the cost of memory and speed, if it can detect more 
kinds of error? Should I just compile everything in, or make features 
selectable by the above-mentioned mechanism of global variables?

Ben.