From f6d2ec7c5eeaa3dd09c3fd4543c79552127a06fe Mon Sep 17 00:00:00 2001 From: Rach Pradhan <54503978+justrach@users.noreply.github.com> Date: Mon, 23 Mar 2026 16:20:08 +0800 Subject: [PATCH] fix hot cache OOM cleanup on insert Add errdefer cleanup for pool-created LRU entries before map.put and cover the failure path with checkAllAllocationFailures. Refs #223 --- src/graph/hot_cache.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/graph/hot_cache.zig b/src/graph/hot_cache.zig index 310fc75..49f471b 100644 --- a/src/graph/hot_cache.zig +++ b/src/graph/hot_cache.zig @@ -72,6 +72,7 @@ pub fn LruCache(comptime V: type) type { // Insert new entry const entry = try self.pool.create(); + errdefer self.pool.destroy(entry); entry.* = .{ .key = key, .value = value }; try self.map.put(key, entry); self.pushFront(entry); @@ -156,6 +157,13 @@ pub const CachedSymbol = struct { line: u32, }; +fn hotCachePutNoLeakOnFailure(allocator: std.mem.Allocator) !void { + var cache = LruCache(u32).init(allocator, 4); + defer cache.deinit(); + + try cache.put(1, 100); +} + // ── Tests ─────────────────────────────────────────────────────────────────── test "basic put and get" { @@ -218,6 +226,10 @@ test "put updates existing key" { try std.testing.expectEqual(@as(?u32, 200), cache.get(1)); } +test "put cleans up pool entry when map.put fails" { + try std.testing.checkAllAllocationFailures(std.testing.allocator, hotCachePutNoLeakOnFailure, .{}); +} + test "remove deletes entry" { var cache = LruCache(u32).init(std.testing.allocator, 4); defer cache.deinit();