Friday, August 31, 2007

Managed malloc and free

The Factor Windows backend has to use manual memory management for Windows runtime callbacks. This opens up a small amount of code to double free errors. And crashes. But Factor is better than that; why crash when you can easily prevent it?

The new malloc adds an entry to a global hashtable, mallocs, whenever new memory is allocated. Upon calling free, it checks that the buffer is still allocated before making the actual memory cleanup call. This managed version of malloc is now the default. To get plain old libc memory allocation, call (malloc) and (free), though the overhead is negligible compared to having your program crash.

Does it work? Yes! Opening a new UI window adds two new mallocs, and closing it takes them away. After running test-all there were two mallocs that went unchecked; both were bugs and corrected in five minutes by inspection. Finally, there is no way to call free twice on a pointer using the managed malloc/free since, if that pointer is not in the mallocs hashtable, an error is thrown. Now, to check that you balance malloc/free calls, you can run your code and make sure the malloc hash doesn't have extra entries. Here's a snippet to count the entries:

mallocs get-global assoc-size .

The code works for calloc and realloc as well, and can be perused here.


Slava Pestov said...

Good job, Doug!

Matt Havener said...

OpenSSL uses a similar method for detecting memory leaks. You can even turn the leak detection on and off, to drill down to your leaks.