aboutsummaryrefslogtreecommitdiff
path: root/lib/std/heap/debug_allocator.zig
diff options
context:
space:
mode:
authorAuguste Rame <19855629+SuperAuguste@users.noreply.github.com>2025-04-02 08:15:04 -0400
committerGitHub <noreply@github.com>2025-04-02 12:15:04 +0000
commitbfab9582c7353c85963b1abfd9844218de9a0cd0 (patch)
tree81e5e97f48c1dcc39842c4b7087b0b57685980f9 /lib/std/heap/debug_allocator.zig
parent896ffe66586035e11080d25deeb9dbba477684fe (diff)
downloadzig-bfab9582c7353c85963b1abfd9844218de9a0cd0.tar.gz
zig-bfab9582c7353c85963b1abfd9844218de9a0cd0.zip
DebugAllocator: Fix bucket removal logic causing segfault/leak (#23390)
Make buckets doubly linked
Diffstat (limited to 'lib/std/heap/debug_allocator.zig')
-rw-r--r--lib/std/heap/debug_allocator.zig18
1 files changed, 16 insertions, 2 deletions
diff --git a/lib/std/heap/debug_allocator.zig b/lib/std/heap/debug_allocator.zig
index ffdc143467..a6b2676b1d 100644
--- a/lib/std/heap/debug_allocator.zig
+++ b/lib/std/heap/debug_allocator.zig
@@ -281,6 +281,7 @@ pub fn DebugAllocator(comptime config: Config) type {
allocated_count: SlotIndex,
freed_count: SlotIndex,
prev: ?*BucketHeader,
+ next: ?*BucketHeader,
canary: usize = config.canary,
fn fromPage(page_addr: usize, slot_count: usize) *BucketHeader {
@@ -782,7 +783,11 @@ pub fn DebugAllocator(comptime config: Config) type {
.allocated_count = 1,
.freed_count = 0,
.prev = self.buckets[size_class_index],
+ .next = null,
};
+ if (self.buckets[size_class_index]) |old_head| {
+ old_head.next = bucket;
+ }
self.buckets[size_class_index] = bucket;
if (!config.backing_allocator_zeroes) {
@@ -935,9 +940,18 @@ pub fn DebugAllocator(comptime config: Config) type {
}
bucket.freed_count += 1;
if (bucket.freed_count == bucket.allocated_count) {
- if (self.buckets[size_class_index] == bucket) {
- self.buckets[size_class_index] = null;
+ if (bucket.prev) |prev| {
+ prev.next = bucket.next;
}
+
+ if (bucket.next) |next| {
+ assert(self.buckets[size_class_index] != bucket);
+ next.prev = bucket.prev;
+ } else {
+ assert(self.buckets[size_class_index] == bucket);
+ self.buckets[size_class_index] = bucket.prev;
+ }
+
if (!config.never_unmap) {
const page: [*]align(page_size) u8 = @ptrFromInt(page_addr);
self.backing_allocator.rawFree(page[0..page_size], page_align, @returnAddress());