mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 07:46:12 +03:00
gtk: fix crash due to accessing invalidated pointer to adwaita notebook (#4926)
#4235 introduced a crash when you closed the last tab in a window. In `NotebookAdw.closeTab` a `defer` was added that references `self`. If the last tab is closed we destroy the window. As part of that process `self` becomes invalid because the window has been de-initialized. The `defer` fires at the end of the function, referencing the invalid pointer and causing a crash. ``` info(surface): surface closed addr=7fffe400a000 debug(gtk): window destroy (process:1032400): Gtk-CRITICAL **: 18:40:17.674: gtk_widget_unparent: assertion 'GTK_IS_WIDGET (widget)' failed Segmentation fault at address 0x7ffff4dad040 /home/jeff/dev/ghostty/src/apprt/gtk/notebook_adw.zig:128:19: 0x340226a in closeTab (ghostty) defer self.forcing_close = false; ^ /home/jeff/dev/ghostty/src/apprt/gtk/notebook.zig:157:40: 0x336ca86 in closeTab (ghostty) .adw => |*adw| adw.closeTab(tab), ^ /home/jeff/dev/ghostty/src/apprt/gtk/Window.zig:468:27: 0x327628d in closeTab (ghostty) self.notebook.closeTab(tab); ^ /home/jeff/dev/ghostty/src/apprt/gtk/Tab.zig:121:25: 0x336581b in remove (ghostty) self.window.closeTab(self); ^ /home/jeff/dev/ghostty/src/apprt/gtk/Surface.zig:207:34: 0x326a213 in remove (ghostty) .tab_ => |t| t.remove(), ^ /home/jeff/dev/ghostty/src/apprt/gtk/Surface.zig:722:30: 0x31e3a3a in close (ghostty) self.container.remove(); ^ /home/jeff/dev/ghostty/src/Surface.zig:733:26: 0x31e1dc4 in close (ghostty) self.rt_surface.close(self.needsConfirmQuit()); ^ /home/jeff/dev/ghostty/src/Surface.zig:925:23: 0x31e143e in handleMessage (ghostty) self.close(); ^ /home/jeff/dev/ghostty/src/App.zig:486:34: 0x31e2d05 in surfaceMessage (ghostty) try surface.handleMessage(msg); ^ /home/jeff/dev/ghostty/src/App.zig:252:62: 0x31e3005 in drainMailbox (ghostty) .surface_message => |msg| try self.surfaceMessage(msg.surface, msg.message), ^ /home/jeff/dev/ghostty/src/App.zig:138:26: 0x31e378e in tick (ghostty) try self.drainMailbox(rt_app); ^ /home/jeff/dev/ghostty/src/apprt/gtk/App.zig:1279:31: 0x31e3e42 in run (ghostty) try self.core_app.tick(self); ^ /home/jeff/dev/ghostty/src/main_ghostty.zig:112:24: 0x31e52f4 in main (ghostty) try app_runtime.run(); ^ /nix/store/h6lccra69nr23676qq32h9qn1fba24v1-zig-0.13.0/lib/std/start.zig:524:37: 0x31e5e0e in main (ghostty) const result = root.main() catch |err| { ^ ???:?:?: 0x7ffff682a1fb in ??? (libc.so.6) Unwind information for `libc.so.6:0x7ffff682a1fb` was not available, trace may be incomplete fish: Job 2, './zig-out/bin/ghostty --config-…' terminated by signal SIGABRT (Abort) ```
This commit is contained in:
@ -125,7 +125,12 @@ pub const NotebookAdw = struct {
|
||||
// as true so that the close_page call below doesn't request
|
||||
// confirmation.
|
||||
self.forcing_close = true;
|
||||
defer self.forcing_close = false;
|
||||
const n = self.nPages();
|
||||
defer {
|
||||
// self becomes invalid if we close the last page because we close
|
||||
// the whole window
|
||||
if (n > 1) self.forcing_close = false;
|
||||
}
|
||||
|
||||
const page = c.adw_tab_view_get_page(self.tab_view, @ptrCast(tab.box)) orelse return;
|
||||
c.adw_tab_view_close_page(self.tab_view, page);
|
||||
@ -143,6 +148,8 @@ pub const NotebookAdw = struct {
|
||||
c.g_object_unref(tab.box);
|
||||
}
|
||||
|
||||
// `self` will become invalid after this call because it will have
|
||||
// been freed up as part of the process of closing the window.
|
||||
c.gtk_window_destroy(tab.window.window);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user