Sunday, November 13, 2016

Valgrind is a well known memory debugging tool. It doesn't seem to officially support FreeBSD, but, luckily, it's available in FreeBSD ports.

Using it is not hard (at least on a basic level), but requires some patience and attention.

Fortunately, libvirt comes provides an easy interface for adding unit tests, and it could be used for running with valgrind as well. Obviously, tests should cover code paths we want to test, but it's still much more convenient than triggering all the stuff manually.

Individual tests could be executed like this:

VIR_TEST_RANGE=22 VIR_TEST_DEBUG=1 ./tests/bhyvexml2argvtest

bhyvexml2argvtest is a test that checks that the bhyve driver converts XML to a proper set of actual bhyve(8) commands. VIR_TEST_RANGE tests to run only test #22 from the suite, and VIR_TEST_DEBUG=1 makes it produce more verbose output.

We can see that we call virAsnprintf a few times to populate xml, args, ldargs and dmargs, but later, in the cleanup section, we only free xml and args, leaking ldargs and dmargs, just like valgrind reported.

Now trying to fix that by adding two VIR_FREE calls for leaked variables and try again.

After running the test again, this warning is gone (yay!), so moving to the next one:

Finally, things are getting clear: bhyveBuildNetArgStr was calling virNetDevTapCreateInBridgePort that is mocked for tests. And the mocked version does not free ifname before calling strdup on it, so it's never freed again. The rest of the fix is trivial, problem solved.

All in all, this appears like an interesting and useful exercise. This is probably too detailed, but hopefully it'll be useful for somebody who's just starting the journey of searching for memory leaks (like myself).