#Unreachable memory as leaks DebugAllocator

1 messages · Page 1 of 1 (latest)

vital raven
#

So I wrote a custom allocator that tracks allocations and can detect leaks, it's similar to GPA but only acuses leaks if the allocated memory is not referenced anywhere. It uses comptime to generate a code that will visit your application searching for pointers, because of this it requires a bit extra work.

The idea behind this is, that programs doesnt need to free memory at the end, the OS aready does this for you, but GPA requires you to free memory otherwise you will endup with a lot of false positives.

As a bonus you can check leaks at anytime.

What you guys think?

https://gist.github.com/lassade/c6c00d377cff8420904598b1874c02c6

Gist

A allocator with leak test that only accuses unreachable memory as leaked. You can then don't bother to free memory at the end of your program, can check for leaks many times during the exe...

lofty nebula
#

interesting

#

so i assume it starts by scanning the stack

#

if i have a pointer to a heap-allocated A on the stack, and A contains a pointer to heap-allocated B but that pointer isn't on the stack anywhere, will it tell that the B is reachable?

rough scaffold
#

Interesting concept, I'd have to experiment around with it some in a real application to see how it works out in practice

cerulean sparrow
#

That's pretty neat!

I did not see any distinction between direct and indirect leaks, that would be super cool to have also, because it helps you know what leaks you should fix first. You would have to scan the non reachable blocks looking for pointers and generate a graph and then do the classification based on if the block has pointers pointing to it. The difficulty is in detecting cycles, and that could be another category, like a "cyclic leak" or something like that, I've seen code that computes the strongly connected components of the graph to achieve that. I wonder how LeakSanitizer does it.

It looks like you have access to type information during the computation of reachable blocks, I did not know that zig had runtime type information, that very cool!

Very nice project !

cerulean sparrow
cerulean sparrow
lofty nebula
#

true

vital raven
#

I update the gist with some fixes, so it basically works like this:

pub fn main() !void {
    const App = struct {
        input: []u8,
    };
    var da = DebugAllocator{};
    var app = try da.allocator().create(App);
    app.input = try da.allocator().alloc(u8, 512);
    app.input = try da.allocator().alloc(u8, 256); // leak!

    var leak_check = try da.detectLeaks();
    defer leak_check.deinit();
    // you have to call manually `track` or `trackChild` on each object you want to track
    // usually eveything will be inside the App you you will only need to call it once
    leak_check.track(app);
    leak_check.summary();
}
#

For some complex types like MultiArrayList you have to implement a custom function called trackMem and call trackChildren on each indivitual member

#

In my use case I have a Game struct that encapsulates my entire game, so with a single track call the DebugAllocator is tracking the all the memory. It's triggering a false positive comming from std.HashMap*s but will replace it anyways

#

And now I don't have to worry about freeing memory on exit!

#

it's a good thing to point out that, the leak check is very slow right now!

vital raven
#

To be correct, formating std.builtin.StackTrace is the slow part, Yey! theres nothing else slowing down the code, so leaking will also probaly hang the app as well when calling inside a loop

cerulean sparrow
#

Having the type information really is great for this application, you could even make a garbage collector