From 5cc8a0daff900f65b45725db063e0186db580ee6 Mon Sep 17 00:00:00 2001 From: Nikolay Govorov Date: Mon, 4 May 2026 17:21:15 +0100 Subject: [PATCH 1/2] Fix v8 crash --- src/browser/Browser.zig | 1 - src/browser/Session.zig | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/browser/Browser.zig b/src/browser/Browser.zig index c29c796e..18a674da 100644 --- a/src/browser/Browser.zig +++ b/src/browser/Browser.zig @@ -86,7 +86,6 @@ pub fn closeSession(self: *Browser) void { if (self.session) |*session| { session.deinit(); self.session = null; - self.env.memoryPressureNotification(.critical); } } diff --git a/src/browser/Session.zig b/src/browser/Session.zig index 5e8141ca..e8f80e38 100644 --- a/src/browser/Session.zig +++ b/src/browser/Session.zig @@ -105,6 +105,12 @@ pub fn deinit(self: *Session) void { self.removePage(); } self.cookie_jar.deinit(); + + // Force V8 to flush any remaining weak callbacks while + // fc_identity_pool is still alive. Identity structs allocated from + // this pool back V8 weak-callback parameters; freeing the pool first + // would leave dangling pointers that segfault on the next GC. + self.browser.env.memoryPressureNotification(.critical); self.fc_identity_pool.deinit(); self.storage_shed.deinit(self.browser.app.allocator); From e5a9f8ba2ef040ca64bac6db3f3ce3251131824c Mon Sep 17 00:00:00 2001 From: Nikolay Govorov Date: Mon, 4 May 2026 18:12:47 +0100 Subject: [PATCH 2/2] Fix ony more crash --- src/cdp/CDP.zig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cdp/CDP.zig b/src/cdp/CDP.zig index a56c5f30..a235fda2 100644 --- a/src/cdp/CDP.zig +++ b/src/cdp/CDP.zig @@ -365,6 +365,16 @@ pub fn disposeBrowserContext(self: *CDP, browser_context_id: []const u8) bool { if (std.mem.eql(u8, bc.id, browser_context_id) == false) { return false; } + // Reentrant teardown from a CDP message drained inside HttpClient.syncRequest. + // Tearing down the browser context here would free Session/Page state + // that the unwinding script-eval frame above us is about to dereference + // (see Session.removePage's matching guard). Defer cleanup to + // CDP.deinit at connection close, by which time eval has unwound. + if (bc.session.currentPage()) |page| { + if (page.frame._script_manager.base.is_evaluating) { + return true; + } + } bc.deinit(); self.browser.closeSession(); self.browser_context = null;