Handle Linux process-tree exit races

Treat procfs child-list disappearance as normal process exit during captured command cleanup.
This commit is contained in:
Pranit committed 2026-08-17 14:01:50 -04:00
1 parent 4f2d110f58
commit 04547bf4e5
1 file changed
+17 -2
+17 -2
View File
@@ -130,8 +130,10 @@ pub const Tracker = struct {
};
defer file.close(io_mod.getIo());
var buffer: [64 * 1024]u8 = undefined;
var reader = file.readerStreaming(io_mod.getIo(), &.{});
const read_len = try reader.interface.readSliceShort(&buffer);
const read_len = readLinuxChildrenFile(file, &buffer) catch |err| switch (err) {
error.ProcessNotFound => return,
else => return err,
};
var children = std.mem.tokenizeAny(u8, buffer[0..read_len], " \t\r\n");
while (children.next()) |pid_text| {
const pid = std.fmt.parseInt(std.posix.pid_t, pid_text, 10) catch continue;
@@ -176,6 +178,19 @@ pub const Tracker = struct {
}
};
fn readLinuxChildrenFile(file: std.Io.File, buffer: []u8) !usize {
if (comptime builtin.os.tag != .linux) return error.ProcessTreeUnsupported;
while (true) {
const result = std.posix.system.read(file.handle, buffer.ptr, buffer.len);
switch (std.posix.errno(result)) {
.SUCCESS => return @intCast(result),
.INTR => continue,
.SRCH, .NOENT => return error.ProcessNotFound,
else => return error.ProcessTreeInspectionFailed,
}
}
}
fn captureIdentity(alloc: Allocator, pid: std.posix.pid_t) !Identity {
return switch (builtin.os.tag) {
.linux => .{ .linux_start_ticks = try captureLinuxStartTicks(alloc, pid) },