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");
|
@cInclude("unistd.h");
|
||||||
});
|
});
|
||||||
|
|
||||||
arena: std.heap.ArenaAllocator,
|
arena: *std.heap.ArenaAllocator,
|
||||||
cwd: ?[]const u8,
|
cwd: ?[]const u8,
|
||||||
env: ?EnvMap,
|
env: ?EnvMap,
|
||||||
args: [][]const u8,
|
args: [][]const u8,
|
||||||
@ -718,8 +718,15 @@ const Subprocess = struct {
|
|||||||
pub fn init(gpa: Allocator, cfg: Config) !Subprocess {
|
pub fn init(gpa: Allocator, cfg: Config) !Subprocess {
|
||||||
// We have a lot of maybe-allocations that all share the same lifetime
|
// 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.
|
// 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();
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
// Get our env. If a default env isn't provided by the caller
|
// Get our env. If a default env isn't provided by the caller
|
||||||
@ -1055,7 +1062,9 @@ const Subprocess = struct {
|
|||||||
self.stop();
|
self.stop();
|
||||||
if (self.pty) |*pty| pty.deinit();
|
if (self.pty) |*pty| pty.deinit();
|
||||||
if (self.env) |*env| env.deinit();
|
if (self.env) |*env| env.deinit();
|
||||||
|
const arena_alloc = self.arena.child_allocator;
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
|
arena_alloc.destroy(self.arena);
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user