diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 545f205634b3..463b03707e5c 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -884,8 +884,17 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo const path = try fs.path.resolve(allocator, &[_][]const u8{raw_path}); defer allocator.free(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, 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, }; @@ -1136,7 +1145,21 @@ 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}); + 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 }); defer f.close(); // TODO fstat and make sure that the file has the correct size @@ -1354,19 +1377,26 @@ 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 name_start: usize = 0; + if (name_buffer[7] != '\\') { + name_start = 3; + std.mem.copy(u16, name_buffer[3..7], &[_]u16{ '\\', '?', '?', '\\' }); + } + 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_buffer[0 .. len + 4 :0], .{}) catch |err| switch (err) { + const coff_file = fs.openFileAbsoluteW(name, .{}) catch |err| switch (err) { error.FileNotFound => return error.MissingDebugInfo, else => return err, };