mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 01:24:49 +01:00
crash_report: finish reverting panic changes
This commit is contained in:
parent
381e231468
commit
251f54d1d7
2 changed files with 40 additions and 26 deletions
|
|
@ -1,14 +1,31 @@
|
|||
/// We override the panic implementation to our own one, so we can print our own information before
|
||||
/// calling the default panic handler. This declaration must be re-exposed from `@import("root")`.
|
||||
pub const panic = std.debug.FullPanic(panicImpl);
|
||||
|
||||
/// We let std install its segfault handler, but we override the target-agnostic handler it calls,
|
||||
/// so we can print our own information before calling the default segfault logic. This declaration
|
||||
/// must be re-exposed from `@import("root")`.
|
||||
pub const debug = struct {
|
||||
pub const handleSegfault = handleSegfaultImpl;
|
||||
};
|
||||
|
||||
/// Printed in panic messages when suggesting a command to run, allowing copy-pasting the command.
|
||||
/// Set by `main` as soon as arguments are known. The value here is a default in case we somehow
|
||||
/// crash earlier than that.
|
||||
pub var zig_argv0: []const u8 = "zig";
|
||||
|
||||
const enabled = switch (build_options.io_mode) {
|
||||
.threaded => build_options.enable_debug_extensions,
|
||||
.evented => false, // would use threadlocals in a way incompatible with evented
|
||||
};
|
||||
fn handleSegfaultImpl(addr: ?usize, name: []const u8, opt_ctx: ?std.debug.CpuContextPtr) noreturn {
|
||||
@branchHint(.cold);
|
||||
dumpCrashContext() catch {};
|
||||
std.debug.defaultHandleSegfault(addr, name, opt_ctx);
|
||||
}
|
||||
fn panicImpl(msg: []const u8, first_trace_addr: ?usize) noreturn {
|
||||
@branchHint(.cold);
|
||||
dumpCrashContext() catch {};
|
||||
std.debug.defaultPanic(msg, first_trace_addr orelse @returnAddress());
|
||||
}
|
||||
|
||||
pub const AnalyzeBody = if (enabled) struct {
|
||||
pub const AnalyzeBody = struct {
|
||||
parent: ?*AnalyzeBody,
|
||||
sema: *Sema,
|
||||
block: *Sema.Block,
|
||||
|
|
@ -35,15 +52,9 @@ pub const AnalyzeBody = if (enabled) struct {
|
|||
std.debug.assert(current.? == ab); // `Sema.analyzeBodyInner` did not match push/pop calls
|
||||
current = ab.parent;
|
||||
}
|
||||
} else struct {
|
||||
const current: ?noreturn = null;
|
||||
// Dummy implementation, with functions marked `inline` to avoid interfering with tail calls.
|
||||
pub inline fn push(_: AnalyzeBody, _: *Sema, _: *Sema.Block, _: []const Zir.Inst.Index) void {}
|
||||
pub inline fn pop(_: AnalyzeBody) void {}
|
||||
pub inline fn setBodyIndex(_: @This(), _: usize) void {}
|
||||
};
|
||||
|
||||
pub const CodegenFunc = if (enabled) struct {
|
||||
pub const CodegenFunc = struct {
|
||||
zcu: *const Zcu,
|
||||
func_index: InternPool.Index,
|
||||
threadlocal var current: ?CodegenFunc = null;
|
||||
|
|
@ -55,21 +66,25 @@ pub const CodegenFunc = if (enabled) struct {
|
|||
std.debug.assert(current.?.func_index == func_index);
|
||||
current = null;
|
||||
}
|
||||
} else struct {
|
||||
const current: ?noreturn = null;
|
||||
// Dummy implementation
|
||||
pub fn start(_: *const Zcu, _: InternPool.Index) void {}
|
||||
pub fn stop(_: InternPool.Index) void {}
|
||||
};
|
||||
|
||||
pub fn dumpCrashContext(terminal: Io.Terminal) Io.Writer.Error!void {
|
||||
fn dumpCrashContext() Io.Writer.Error!void {
|
||||
const S = struct {
|
||||
/// In the case of recursive panics or segfaults, don't print the context for a second time.
|
||||
threadlocal var already_dumped = false;
|
||||
/// TODO: make this unnecessary. It exists because `print_zir` currently needs an allocator,
|
||||
/// but that shouldn't be necessary---it's already only used in one place.
|
||||
var crash_heap: [64 * 1024]u8 = undefined;
|
||||
threadlocal var crash_heap: [64 * 1024]u8 = undefined;
|
||||
};
|
||||
if (S.already_dumped) return;
|
||||
S.already_dumped = true;
|
||||
|
||||
// TODO: this does mean that a different thread could grab the stderr mutex between the context
|
||||
// and the actual panic printing, which would be quite confusing.
|
||||
const stderr = std.debug.lockStderr(&.{});
|
||||
defer std.debug.unlockStderr();
|
||||
const w = &stderr.file_writer.interface;
|
||||
|
||||
const w = terminal.writer;
|
||||
try w.writeAll("Compiler crash context:\n");
|
||||
|
||||
if (CodegenFunc.current) |*cg| {
|
||||
|
|
@ -155,5 +170,3 @@ const Zcu = @import("Zcu.zig");
|
|||
const InternPool = @import("InternPool.zig");
|
||||
const dev = @import("dev.zig");
|
||||
const print_zir = @import("print_zir.zig");
|
||||
|
||||
const build_options = @import("build_options");
|
||||
|
|
|
|||
|
|
@ -52,11 +52,12 @@ pub const std_options: std.Options = .{
|
|||
};
|
||||
pub const std_options_cwd = if (native_os == .wasi) wasi_cwd else null;
|
||||
|
||||
pub const debug = struct {
|
||||
pub fn printCrashContext(terminal: Io.Terminal) void {
|
||||
crash_report.dumpCrashContext(terminal) catch {};
|
||||
}
|
||||
const crash_report_enabled = switch (build_options.io_mode) {
|
||||
.threaded => build_options.enable_debug_extensions,
|
||||
.evented => false, // would use threadlocals in a way incompatible with evented
|
||||
};
|
||||
pub const panic = if (crash_report_enabled) crash_report.panic else std.debug.FullPanic(std.debug.defaultPanic);
|
||||
pub const debug = if (crash_report_enabled) crash_report.debug else struct {};
|
||||
|
||||
var preopens: std.process.Preopens = .empty;
|
||||
pub fn wasi_cwd() Io.Dir {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue