Tracking Memory Leaks in Odin
Odin requires the user to manage memory. For those not familiar with the task,
there is a handy way to know if there is a memory leak, or an allocation that is
not freed or reclaimed. Not only that but this shows the file and line where the
leaked allocation happened.
These notes are compiled from Karl Zylinski's
YouTube Video on the same topic
and
Odin's Overview.
TL;DR
This snippet uses a few other concepts such as when ODIN_DEBUG
and
defer block
.
import "core:mem"
main :: proc () {
// this enables the tracking allocator logic when compiled with -debug
when ODIN_DEBUG {
// create the allocator
tracker : mem.Tracking_Allocator
// initialize the allocator to wrap around the default allocator in context
mem.tracking_allocator_init(&tracker, context.allocator)
// convert the tracking allocator to the allocator interface and make it the
// default allocator
context.allocator = mem.tracking_allocator(&tracker)
defer {
fmt.eprintf("Tracking allocator results:\n")
if len(tracker.allocation_map) > 0 {
for _, leak in tracker.allocation_map {
fmt.eprintf("%v leaked %m\n", leak.location, leak.size)
}
} else {
fmt.eprintf("No leaks!\n")
}
fmt.eprintf("Tracking allocator bad frees:\n")
if len(tracker.bad_free_array) > 0 {
for b in tracker.bad_free_array {
fmt.eprintf("Bad free at: %v\n", b.location)
}
} else {
fmt.eprintf("No bad frees!\n")
}
mem.tracking_allocator_destroy(&tracker)
}
}
// do stuff here
}
Notes
When implementing this allocator I noticed a lot of my leaks were from string
and cstring
conversions during Lua embedding. The procedure group
delete
makes it easy to
manage.
This has performance issues so it should just be used during development and not
for releases. This is where the when ODIN_DEBUG
block is useful.
References