From 76fc435e88750b6ed750ea9593593d4cd05d6449 Mon Sep 17 00:00:00 2001 From: star-tek-mb Date: Mon, 14 Nov 2022 21:47:37 +0500 Subject: [PATCH 1/3] windows: fix stacktrace on UNC wsl path --- lib/std/debug.zig | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 545f205634b3..dd1406e33e79 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -884,8 +884,11 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo const path = try fs.path.resolve(allocator, &[_][]const u8{raw_path}); defer allocator.free(path); + const unc_path = try std.fmt.allocPrint(allocator, "\\??\\{s}{s}", .{if (path[0] == '\\') "UNC" else "", path}); + defer allocator.free(unc_path); + di.debug_data = PdbOrDwarf{ .pdb = undefined }; - di.debug_data.pdb = pdb.Pdb.init(allocator, path) catch |err| switch (err) { + di.debug_data.pdb = pdb.Pdb.init(allocator, unc_path) catch |err| switch (err) { error.FileNotFound, error.IsDir => return error.MissingDebugInfo, else => return err, }; @@ -1354,19 +1357,25 @@ pub const DebugInfo = struct { var name_buffer: [windows.PATH_MAX_WIDE + 4:0]u16 = undefined; // openFileAbsoluteW requires the prefix to be present - mem.copy(u16, name_buffer[0..4], &[_]u16{ '\\', '?', '?', '\\' }); + mem.copy(u16, name_buffer[0..7], &[_]u16{ '\\', '?', '?', '\\', 'U', 'N', 'C' }); const len = windows.kernel32.K32GetModuleFileNameExW( process_handle, module, - @ptrCast(windows.LPWSTR, &name_buffer[4]), + @ptrCast(windows.LPWSTR, &name_buffer[7]), windows.PATH_MAX_WIDE, ); assert(len > 0); + var begin: usize = 0; + if (name_buffer[7] != '\\') { + begin = 3; + std.mem.copy(u16, name_buffer[3..7], &[_]u16{ '\\', '?', '?', '\\' }); + } + var name_w16 = std.mem.collapseRepeats(u16, name_buffer[begin..len+7], '\\'); const obj_di = try self.allocator.create(ModuleDebugInfo); errdefer self.allocator.destroy(obj_di); - const coff_file = fs.openFileAbsoluteW(name_buffer[0 .. len + 4 :0], .{}) catch |err| switch (err) { + const coff_file = fs.openFileAbsoluteW(name_w16, .{}) catch |err| switch (err) { error.FileNotFound => return error.MissingDebugInfo, else => return err, }; From a890b8d0279327f16865eb2fcd8cdb8d69013f26 Mon Sep 17 00:00:00 2001 From: star-tek-mb Date: Mon, 14 Nov 2022 22:34:19 +0500 Subject: [PATCH 2/3] windows: stacktrace fix line info printing --- lib/std/debug.zig | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index dd1406e33e79..3bb23dceedb9 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1139,7 +1139,16 @@ fn readMachODebugInfo(allocator: mem.Allocator, macho_file: File) !ModuleDebugIn fn printLineFromFileAnyOs(out_stream: anytype, line_info: LineInfo) !void { // Need this to always block even in async I/O mode, because this could potentially // be called from e.g. the event loop code crashing. - var f = try fs.cwd().openFile(line_info.file_name, .{ .intended_io_mode = .blocking }); + var path = line_info.file_name; + + if (native_os == .windows) { + var buffer: [std.fs.MAX_PATH_BYTES*2]u8 = undefined; + var fba = std.heap.FixedBufferAllocator.init(&buffer); + var resolved_path = try std.fs.path.resolve(fba.allocator(), &.{path}); + path = try std.fmt.allocPrint(fba.allocator(), "\\??\\{s}{s}", .{if (resolved_path[0] == '\\') "UNC" else "", resolved_path}); + } + + var f = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking }); defer f.close(); // TODO fstat and make sure that the file has the correct size From fcf2f2ce08666b859a18ae76ace4b0adccddd7ea Mon Sep 17 00:00:00 2001 From: star-tek-mb Date: Tue, 15 Nov 2022 13:02:51 +0500 Subject: [PATCH 3/3] windows: fix native build --- lib/std/debug.zig | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 3bb23dceedb9..463b03707e5c 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -884,8 +884,14 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo const path = try fs.path.resolve(allocator, &[_][]const u8{raw_path}); defer allocator.free(path); - const unc_path = try std.fmt.allocPrint(allocator, "\\??\\{s}{s}", .{if (path[0] == '\\') "UNC" else "", path}); + var unc_path: []const u8 = undefined; + if (path[0] == '\\') { + unc_path = try std.fmt.allocPrint(allocator, "\\??\\UNC{s}", .{path}); + } else { + unc_path = try std.fmt.allocPrint(allocator, "\\??\\{s}", .{path}); + } defer allocator.free(unc_path); + // path normalized later in openFile di.debug_data = PdbOrDwarf{ .pdb = undefined }; di.debug_data.pdb = pdb.Pdb.init(allocator, unc_path) catch |err| switch (err) { @@ -1142,10 +1148,15 @@ fn printLineFromFileAnyOs(out_stream: anytype, line_info: LineInfo) !void { var path = line_info.file_name; if (native_os == .windows) { - var buffer: [std.fs.MAX_PATH_BYTES*2]u8 = undefined; + var buffer: [std.fs.MAX_PATH_BYTES * 2]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buffer); var resolved_path = try std.fs.path.resolve(fba.allocator(), &.{path}); - path = try std.fmt.allocPrint(fba.allocator(), "\\??\\{s}{s}", .{if (resolved_path[0] == '\\') "UNC" else "", resolved_path}); + if (resolved_path[0] == '\\') { + path = try std.fmt.allocPrint(fba.allocator(), "\\??\\UNC{s}", .{resolved_path}); + } else { + path = try std.fmt.allocPrint(fba.allocator(), "\\??\\{s}", .{resolved_path}); + } + // path normalized later in openFile } var f = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking }); @@ -1374,17 +1385,18 @@ pub const DebugInfo = struct { windows.PATH_MAX_WIDE, ); assert(len > 0); - var begin: usize = 0; + var name_start: usize = 0; if (name_buffer[7] != '\\') { - begin = 3; + name_start = 3; std.mem.copy(u16, name_buffer[3..7], &[_]u16{ '\\', '?', '?', '\\' }); } - var name_w16 = std.mem.collapseRepeats(u16, name_buffer[begin..len+7], '\\'); + const name_len = try std.os.windows.normalizePath(u16, name_buffer[name_start .. len + 7]); + const name = name_buffer[name_start .. name_start + name_len]; const obj_di = try self.allocator.create(ModuleDebugInfo); errdefer self.allocator.destroy(obj_di); - const coff_file = fs.openFileAbsoluteW(name_w16, .{}) catch |err| switch (err) { + const coff_file = fs.openFileAbsoluteW(name, .{}) catch |err| switch (err) { error.FileNotFound => return error.MissingDebugInfo, else => return err, };