diff options
Diffstat (limited to 'src/pardes/app.zig')
| -rw-r--r-- | src/pardes/app.zig | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/pardes/app.zig b/src/pardes/app.zig index 1302556..8b43791 100644 --- a/src/pardes/app.zig +++ b/src/pardes/app.zig @@ -405,10 +405,21 @@ fn logFn( pub const panic = std.debug.FullPanic(panicImpl); -fn panicImpl(msg: []const u8, _: ?usize) noreturn { - // The ROM path deliberately: a panic may BE the console writer failing, and `ets_printf` shares - // nothing with `uart.write` except the FIFO itself. - soc.rom.print("\r\nMARK PARDES_PANIC %s\r\n", .{msg.ptr}); +fn panicImpl(msg: []const u8, first_trace_addr: ?usize) noreturn { + // The fixed text goes out through the ROM deliberately: a panic may BE the console writer + // failing, and `ets_printf` shares nothing with `uart.write` except the FIFO itself. + // + // The MESSAGE does not, and that is a correction rather than a preference. `msg` is a Zig SLICE + // and `%s` reads until a NUL, so handing `msg.ptr` to printf prints the message and then + // whatever happens to sit after it in memory until a zero byte turns up. Literals get away with + // it; std's own panics do not, because they are formatted into a buffer - "index out of bounds: + // index 5, len 3" - and carry no terminator. `uart.write` takes a length. + soc.rom.print("\r\nMARK PARDES_PANIC ", .{}); + uart.write(msg); + // The address is what makes it actionable: addr2line against the ELF in zig-out turns it into a + // source line, and without it a panic message names a KIND of failure with no way to find which + // one of them happened. Zero when the caller had no return address to give. + soc.rom.print("\r\nMARK PARDES_PANIC_AT 0x%08x\r\n", .{@as(u32, @truncate(first_trace_addr orelse 0))}); while (true) {} } |
