mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
fix(termio): heap-allocate Subprocess arena so alloc doesn't get lost
Previously, if `cfg.env` was `null` and we made our own `EnvMap`, it would experience a bad access when trying to deinit because the alloc it stored had a pointer to the stack allocated arena object, which would be invalid.
This commit is contained in:
@ -702,7 +702,7 @@ const Subprocess = struct {
|
||||
@cInclude("unistd.h");
|
||||
});
|
||||
|
||||
arena: std.heap.ArenaAllocator,
|
||||
arena: *std.heap.ArenaAllocator,
|
||||
cwd: ?[]const u8,
|
||||
env: ?EnvMap,
|
||||
args: [][]const u8,
|
||||
@ -718,8 +718,15 @@ const Subprocess = struct {
|
||||
pub fn init(gpa: Allocator, cfg: Config) !Subprocess {
|
||||
// We have a lot of maybe-allocations that all share the same lifetime
|
||||
// so use an arena so we don't end up in an accounting nightmare.
|
||||
var arena = std.heap.ArenaAllocator.init(gpa);
|
||||
errdefer arena.deinit();
|
||||
//
|
||||
// The arena is heap-allocated because if we have our own
|
||||
// env map it retains a pointer to it via the allocator.
|
||||
const arena = try gpa.create(std.heap.ArenaAllocator);
|
||||
arena.* = std.heap.ArenaAllocator.init(gpa);
|
||||
errdefer {
|
||||
arena.deinit();
|
||||
gpa.destroy(arena);
|
||||
}
|
||||
const alloc = arena.allocator();
|
||||
|
||||
// Get our env. If a default env isn't provided by the caller
|
||||
@ -1055,7 +1062,9 @@ const Subprocess = struct {
|
||||
self.stop();
|
||||
if (self.pty) |*pty| pty.deinit();
|
||||
if (self.env) |*env| env.deinit();
|
||||
const arena_alloc = self.arena.child_allocator;
|
||||
self.arena.deinit();
|
||||
arena_alloc.destroy(self.arena);
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user