Compare commits

...

6 Commits

Author SHA1 Message Date
Julian
cf60fefc8e
Merge eb74a9d63d into f845fa04a0 2024-11-21 10:48:29 +05:00
Alex Rønne Petersen
f845fa04a0 std.debug: Gracefully handle process_vm_readv() EPERM in MemoryAccessor.read().
Closes #21815.
2024-11-20 23:07:46 +01:00
Parzival-3141
eb74a9d63d group error and trace for reporting in build runner
Unlike the previous commit, this ensures that the error message and trace are
printed together.
2024-08-27 00:44:55 -04:00
Parzival-3141
a49d1827fe store error trace and defer printing 2024-08-26 21:08:37 -04:00
Parzival-3141
0c5b9cb0c0 print message instead of panicking on buffer overrun 2024-08-26 18:23:44 -04:00
Parzival-3141
3185ff0b9f show errorReturnTrace when Step.makeFn errors 2024-08-26 18:23:44 -04:00
3 changed files with 33 additions and 12 deletions

View File

@ -894,7 +894,7 @@ fn printStepFailure(
try ttyconf.setColor(stderr, .reset);
}
try stderr.writeAll("\n");
} else if (s.result_error_msgs.items.len > 0) {
} else if (s.result_error_msgs.items.len > 0 or s.make_error_trace != null) {
try ttyconf.setColor(stderr, .red);
try stderr.writeAll(" failure\n");
try ttyconf.setColor(stderr, .reset);
@ -1103,7 +1103,7 @@ fn workerMakeOneStep(
// No matter the result, we want to display error/warning messages.
const show_compile_errors = !run.prominent_compile_errors and
s.result_error_bundle.errorMessageCount() > 0;
const show_error_msgs = s.result_error_msgs.items.len > 0;
const show_error_msgs = s.result_error_msgs.items.len > 0 or s.make_error_trace != null;
const show_stderr = s.result_stderr.len > 0;
if (show_error_msgs or show_compile_errors or show_stderr) {
@ -1217,6 +1217,14 @@ pub fn printErrorMessages(
try stderr.writeAll(msg);
try stderr.writeAll("\n");
}
if (failing_step.make_error_trace) |make_err| {
try ttyconf.setColor(stderr, .red);
try stderr.writeAll("error: ");
try ttyconf.setColor(stderr, .reset);
try stderr.writer().print("this step's make function failed with error {s}", .{@errorName(make_err.err)});
if (make_err.trace) |trace| try trace.format("", .{}, stderr.writer());
}
}
fn steps(builder: *std.Build, out_stream: anytype) !void {

View File

@ -41,6 +41,8 @@ max_rss: usize,
result_error_msgs: std.ArrayListUnmanaged([]const u8),
result_error_bundle: std.zig.ErrorBundle,
make_error_trace: ?MakeErrorTrace,
result_stderr: []const u8,
result_cached: bool,
result_duration_ns: ?u64,
@ -52,6 +54,12 @@ test_results: TestResults,
/// to print along with debugging messages.
debug_stack_trace: []usize,
/// Storage for unhandled errors returned by the make function.
pub const MakeErrorTrace = struct {
err: anyerror,
trace: ?*std.builtin.StackTrace,
};
pub const TestResults = struct {
fail_count: u32 = 0,
skip_count: u32 = 0,
@ -214,6 +222,7 @@ pub fn init(options: StepOptions) Step {
},
.result_error_msgs = .{},
.result_error_bundle = std.zig.ErrorBundle.empty,
.make_error_trace = null,
.result_stderr = "",
.result_cached = false,
.result_duration_ns = null,
@ -223,18 +232,20 @@ pub fn init(options: StepOptions) Step {
}
/// If the Step's `make` function reports `error.MakeFailed`, it indicates they
/// have already reported the error. Otherwise, we add a simple error report
/// here.
/// have already reported the error. Otherwise, we store the error for reporting
/// later.
pub fn make(s: *Step, options: MakeOptions) error{ MakeFailed, MakeSkipped }!void {
const arena = s.owner.allocator;
s.makeFn(s, options) catch |err| switch (err) {
error.MakeFailed => return error.MakeFailed,
error.MakeSkipped => return error.MakeSkipped,
else => {
s.result_error_msgs.append(arena, @errorName(err)) catch @panic("OOM");
return error.MakeFailed;
},
s.makeFn(s, options) catch |err| {
switch (err) {
error.MakeFailed => return error.MakeFailed,
error.MakeSkipped => return error.MakeSkipped,
else => {
s.make_error_trace = .{ .err = err, .trace = @errorReturnTrace() };
return error.MakeFailed;
},
}
};
if (!s.test_results.isSuccess()) {
@ -894,6 +905,7 @@ fn reset(step: *Step, gpa: Allocator) void {
step.result_error_bundle.deinit(gpa);
step.result_error_bundle = std.zig.ErrorBundle.empty;
step.make_error_trace = null;
}
/// Implementation detail of file watching. Prepares the step for being re-evaluated.

View File

@ -48,7 +48,8 @@ fn read(ma: *MemoryAccessor, address: usize, buf: []u8) bool {
switch (linux.E.init(bytes_read)) {
.SUCCESS => return bytes_read == buf.len,
.FAULT => return false,
.INVAL, .PERM, .SRCH => unreachable, // own pid is always valid
.INVAL, .SRCH => unreachable, // own pid is always valid
.PERM => {}, // Known to happen in containers.
.NOMEM => {},
.NOSYS => {}, // QEMU is known not to implement this syscall.
else => unreachable, // unexpected