Blog Archives

Valgrind for Mac OS X – first impressions

Not so long ago, Apple developer Greg Parker, published a patch for a specific revision of Valgrind so that it can work in Mac OS X. You can check the details of how to install it in his webpage, it doesn’t take more than 5 minutes to do it:

I made a simple test to see how well or bad it works, with definitely lost and still reachable memory leaks. The test goes as follows:

#include <stdio.h>
#include <string.h>
/* Global string, still-reachable */
static char *global_str;
int main(int argc, char **argv)
  /* Function-local string,
   * definitely-lost */
  char *str = NULL;
  /* These are 10+1 bytes leaked */
  str = strdup("1234567890");
  /* These are 15+1 bytes leaked */
  global_str = strdup("123456789012345");
  return 0;

We compile it…

$> gcc -o test test.c

Now, let’s see if this valgrind port catches our memory leaks.

$> valgrind --show-reachable=yes --leak-check=full --leak-resolution=high ./test

Well, valgrind runs and we start checking its output:

==13340== LEAK SUMMARY:
==13340== definitely lost: 11 bytes in 1 blocks.
==13340== possibly lost: 0 bytes in 0 blocks.
==13340== still reachable: 316 bytes in 8 blocks.
==13340== suppressed: 0 bytes in 0 blocks.

We were only expecting 11 bytes definitely lost (local-function pointer) and 16 bytes still reachable (global pointer), but we have lots more still reachable. Let’s see the detailed results:

==13340== ERROR
==13340== 11 bytes in 1 blocks are definitely lost in loss record 1 of 4
==13340== at 0x22E53: malloc+99 (in /usr/local/lib/valgrind/x86-darwin/
==13340== by 0x21A3D1: strdup+33 (in /usr/lib/libSystem.B.dylib)
==13340== by 0x1FBB: main+33 (in ./test)
==13340== ERROR
==13340== 16 bytes in 1 blocks are still reachable in loss record 2 of 4
==13340== at 0x22E53: malloc+99 (in /usr/local/lib/valgrind/x86-darwin/
==13340== by 0x21A3D1: strdup+33 (in /usr/lib/libSystem.B.dylib)
==13340== by 0x1FCC: main+50 (in ./test)

Ok, here are our memory leaks. Let’s see what is the other stuff.

==13340== ERROR
==13340== 60 bytes in 1 blocks are still reachable in loss record 3 of 4
==13340== at 0x22E53: malloc+99 (in /usr/local/lib/valgrind/x86-darwin/
==13340== by 0x1F7E89: get_or_create_key_element+157 (in /usr/lib/libSystem.B.dylib)
==13340== by 0x1F7DBB: _keymgr_get_and_lock_processwide_ptr_2+21 (in /usr/lib/libSystem.B.dylib)
==13340== ERROR
==13340== 240 bytes in 6 blocks are still reachable in loss record 4 of 4
==13340== at 0x24DD9: calloc+105 (in /usr/local/lib/valgrind/x86-darwin/
==13340== by 0x1F79D9: dwarf2_unwind_dyld_add_image_hook+40 (in /usr/lib/libSystem.B.dylib)
==13340== by 0x8FE03D61: dyld::registerAddCallback(void (*)(mach_header const*, long))+145 (in /usr/lib/dyld)

As expected (Greg already warned about it) we are getting some leak reports of system libraries, as being still reachable. The “still reachable” means that when the program ended some allocations were done previously using pointers that are ‘global’ to the program, so still reachable when program ended. In other words, valgrind found pointers to allocated memory in the context when the program ended, and the only context available in that time is the global one. All the other contexts (different functions called, even main()) dissappear when the program ends, and pointers declared in those functions which are used to allocate memory are the “definitely lost” ones.

Well, I would say that there is still work to be done, but I don’t see having these system library allocation leak reports a real problem. Once you have linked your programs against Glib, you will get used to see this kind of error reports, but multiplied by 1000. Glib does lots of memory allocations in g_type_init() that are not deallocated with a g_type_deinit() (there is no such function), so they are deallocated by the OS when the program ends. To deal with the ones from Glib, it’s usual to skip using
leak-resolution=high and use Valgrind suppression files.

Probably these reported errors are not comparable to the ones from Glib, but the way to deal with them should be really similar. So, good job Greg! and let’s see if this port can be improved until it’s completely included in Valgrind sources.