Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

windows: fix stacktrace on UNC wsl path #13547

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions lib/std/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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,
};
Expand Down