Loading a heap analyser with LD_PRELOAD, and global scope objects in C++
-
24-06-2021 - |
سؤال
We have written a heap analyser (for reference known as lib_debug
) which overrides free
and malloc
(and others), primarily to monitor for errors such as memory leaks in our applications, which are deployed on a PPC system running Linux. lib_debug
is compiled as a shared library, which is loaded with LD_PRELOAD
as and when needed.
This debugger has worked great up until now; whenever malloc
is called, a memory monitor singleton is created on the stack, which reports on any un-freed memory when this singleton goes out of scope on exit.
However, one of our applications now allocates a std::vector
at the global scope. It appears that this global vector
is being created before our heap analyser is, and most importantly destroyed afterwards. Hence, once in main
if we insert anything into this vector
, lib_debug
thinks we have a memory leak on shutdown.
To illustrate, this is what I believe the sequence of events is:
LD_PRELOAD
loads the symbols fromlib_debug
;std::vector
is created on stack at global scope;lib_debug
initialisation occurs -malloc
has been called somewhere, which causes the actual heap analyser singleton to be created on the stack;- Enter
main
; std::vector::push_back()
occurs, allocating memory on the heap;main
exits;- The
lib_debug
heap analyser singleton goes out of scope, which sees that thevector
hasn't freed its memory - reports error; - The
vector
goes out of global scope, releasing its memory; - Program terminates.
Therefore, is there any way we can guarantee that our LD_PRELOADed
singleton is always the last thing to be deleted, and therefore catch every single free
that occurs in our application?
المحلول
This works if you are using GCC
as your compiler. You can define a function in your library to act as a constructor
, so that code gets executed when your library is loaded.
static int initialize_lib_debug () __attribute__((constructor));
static int initialize_lib_debug () {
/* ... */
}