summaryrefslogtreecommitdiff
path: root/src/pardes/app.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/pardes/app.zig')
-rw-r--r--src/pardes/app.zig19
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) {}
}