[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Here are some technical details about the functioning of the memory debugger. This can help you understand better how it works, and I think this can help you use the debugger in a more productive fashion.
In each `new' or `delete' call, we check whenever we have been initialized. If not, we call the initialization function that parses the `.map' file, sets the debugging options and so on. When program exits the memory debugger checks for unfreed memory block, displays statistics and so on. This is done by declaring a dummy static variable at the very end of memory debugger module and the shutdown function being called from its destructor.
The only trick used in memory debugger is used to get the address from where
`new' and `delete' have been called. This is a processor-dependent
issue, alas we can't do it in a platform-independent fashion. To support
doing this on different platforms we define a macro called
GET_CALL_ADDRESS()
. We pass the first argument of the procedure we're
invoking GET_CALL_ADDRESS()
from and we get the address from were we
were called in a variable called `addr'.
Here are details on how we're doing it on different platforms:
+-----------------+ higher addresses | arg2 | ^ +-----------------+ | | arg1 | | +-----------------+ | | return address | | +-----------------+ lower addresses |
This means that if we take the address of first argument of the procedure and go one machine word back, we'll get the address of the function's return address word. Now we peek it from there and we have the return address. This is embedded into a macro that looks like this:
#define GET_CALL_ADDRESS(firstarg) \ address addr = ((address*)&firstarg) [-1]; |
Where `address' is a shortcut for type `void*'.
__builtin_return_address()
. If we invoke it
with the argument zero, it returns just what we need; the address from where
our procedure was called. Thus, an almost-cross-platform
GET_CALL_ADDRESS()
is implemented this way:
#if (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 8) # define GET_CALL_ADDRESS(firstarg) \ address addr = (address)__builtin_return_address(0); #endif |
Thus, if you can't get `memdbg.sh' to work, you should find a newer GCC; this should always help.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |