Memory leaks are caused by allocating memory blocks and not releasing them after their last use. In most modern programs, dynamic data structures are used quite extensively. In this case, only knowing the allocation site of leaked memory blocks, as reported by most current tools, is often not enough to fix said leaks. It is also possible that all pointers to a memory block were overwritten during the execution of a program, in which case more information is required as well. In this paper we describe an approach which uses a combination of dynamic instrumentation and garbage collection techniques to keep track of all memory blocks and their referring pointers. At the end of the execution, we can inform the user where exactly the last pointer to a memory block has been lost, as well as where this pointer was created. Another possibility is tracking a specific memory block during the life time of an execution and reporting the creation and destruction of all references to it. All this can be done without the need for recompilation or relinking.