From 2193f7c4a2b56f67bf07d27c3f715cf3969c392f Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Mon, 18 Apr 2022 13:11:37 +0200 Subject: wasm: Add support for debug info This implements basic DWARF output when building for the wasm target. Stacktraces, however, are currently not supported. --- lib/std/debug.zig | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/std/debug.zig') diff --git a/lib/std/debug.zig b/lib/std/debug.zig index e00c0a21a2..6a0d4dac93 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -114,6 +114,10 @@ pub fn detectTTYConfig() TTY.Config { pub fn dumpCurrentStackTrace(start_addr: ?usize) void { nosuspend { const stderr = io.getStdErr().writer(); + if (comptime builtin.target.isWasm()) { + stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; + return; + } if (builtin.strip_debug_info) { stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; return; -- cgit v1.2.3 From be08d2bdbd2f64ccb9ef0f985a57a4bf89b9aebb Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Sun, 17 Apr 2022 19:41:05 +0200 Subject: wasm: Fix unreachable paths When the last instruction is a debug instruction, the type of it is void. Similarly for 'noreturn' emit an 'unreachable' instruction to tell the wasm-validator the path cannot be reached. Also respect the '--strip' flag in the self-hosted wasm linker and not emit a 'name' section when the flag is set to `true`. --- lib/std/debug.zig | 36 ++++++++++++++++++++++++++++++++++-- src/arch/wasm/CodeGen.zig | 3 ++- src/link/Wasm.zig | 2 +- 3 files changed, 37 insertions(+), 4 deletions(-) (limited to 'lib/std/debug.zig') diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 6a0d4dac93..b600f7245a 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -113,11 +113,14 @@ pub fn detectTTYConfig() TTY.Config { /// TODO multithreaded awareness pub fn dumpCurrentStackTrace(start_addr: ?usize) void { nosuspend { - const stderr = io.getStdErr().writer(); if (comptime builtin.target.isWasm()) { - stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; + if (native_os == .wasi) { + const stderr = io.getStdErr().writer(); + stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; + } return; } + const stderr = io.getStdErr().writer(); if (builtin.strip_debug_info) { stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; return; @@ -138,6 +141,13 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void { /// TODO multithreaded awareness pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { nosuspend { + if (comptime builtin.target.isWasm()) { + if (native_os == .wasi) { + const stderr = io.getStdErr().writer(); + stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; + } + return; + } const stderr = io.getStdErr().writer(); if (builtin.strip_debug_info) { stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; @@ -208,6 +218,13 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT /// TODO multithreaded awareness pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void { nosuspend { + if (comptime builtin.target.isWasm()) { + if (native_os == .wasi) { + const stderr = io.getStdErr().writer(); + stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; + } + return; + } const stderr = io.getStdErr().writer(); if (builtin.strip_debug_info) { stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; @@ -1138,6 +1155,8 @@ pub const DebugInfo = struct { return self.lookupModuleWin32(address); } else if (native_os == .haiku) { return self.lookupModuleHaiku(address); + } else if (comptime builtin.target.isWasm()) { + return self.lookupModuleWasm(address); } else { return self.lookupModuleDl(address); } @@ -1353,6 +1372,12 @@ pub const DebugInfo = struct { _ = address; @panic("TODO implement lookup module for Haiku"); } + + fn lookupModuleWasm(self: *DebugInfo, address: usize) !*ModuleDebugInfo { + _ = self; + _ = address; + @panic("TODO implement lookup module for Wasm"); + } }; pub const ModuleDebugInfo = switch (native_os) { @@ -1632,6 +1657,13 @@ pub const ModuleDebugInfo = switch (native_os) { return getSymbolFromDwarf(relocated_address, &self.dwarf); } }, + .wasi => struct { + pub fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo { + _ = self; + _ = address; + return SymbolInfo{}; + } + }, else => DW.DwarfInfo, }; diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index b701299e73..6cec3f4a87 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -871,7 +871,8 @@ fn genFunc(self: *Self) InnerError!void { // we emit an unreachable instruction to tell the stack validator that part will never be reached. if (func_type.returns.len != 0 and self.air.instructions.len > 0) { const inst = @intCast(u32, self.air.instructions.len - 1); - if (self.air.typeOfIndex(inst).isNoReturn()) { + const last_inst_ty = self.air.typeOfIndex(inst); + if (!last_inst_ty.hasRuntimeBitsIgnoreComptime() or last_inst_ty.isNoReturn()) { try self.addTag(.@"unreachable"); } } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 1ed733774f..4f72dfe388 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1897,7 +1897,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod if (data_section_index) |data_index| { try self.emitDataRelocations(file, arena, data_index, symbol_table); } - } else { + } else if (!self.base.options.strip) { try self.emitNameSection(file, arena); } } -- cgit v1.2.3