Skip to content
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