authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-10 13:18:28+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-20 19:41:29+01:00
log99649794e965ce76c81cb91a7ff78f3a42d533bc
tree35dad55143aea2e65df6b317b07b1edd4e999b36
parentb0b60cd46854f05c830b51693acd2f1ea7b1ee1a

win


2 files changed, 96 insertions(+), 17 deletions(-)

lib/std/debug.zig+94-17
......@@ -248,7 +248,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c
248248 }
249249
250250 switch (@atomicRmw(u8, &panicking, .Add, 1, .SeqCst)) {
251 0 => {
251 0, 1 => {
252252 const stderr = getStderrStream();
253253 noasync stderr.print(format ++ "\n", args) catch os.abort();
254254 if (trace) |t| {
......@@ -256,7 +256,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c
256256 }
257257 dumpCurrentStackTrace(first_trace_addr);
258258 },
259 1 => {
259 2 => {
260260 // TODO detect if a different thread caused the panic, because in that case
261261 // we would want to return here instead of calling abort, so that the thread
262262 // which first called panic can finish printing a stack trace.
......@@ -404,13 +404,15 @@ pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: us
404404
405405/// TODO resources https://github.com/ziglang/zig/issues/4353
406406fn printSourceAtAddressWindows(
407 di: *DebugInfo,
407 di1: *DebugInfo,
408408 out_stream: var,
409409 relocated_address: usize,
410410 tty_config: TTY.Config,
411411) !void {
412 const di = try di1.lookupByAddress(relocated_address);
413
412414 const allocator = getDebugInfoAllocator();
413 const base_address = process.getBaseAddress();
415 const base_address = di.base_address;
414416 const relative_address = relocated_address - base_address;
415417
416418 var coff_section: *coff.Section = undefined;
......@@ -630,7 +632,7 @@ pub const TTY = struct {
630632};
631633
632634/// TODO resources https://github.com/ziglang/zig/issues/4353
633fn populateModule(di: *DebugInfo, mod: *Module) !void {
635fn populateModule(di: *ObjectDebugInfo, mod: *Module) !void {
634636 if (mod.populated)
635637 return;
636638 const allocator = getDebugInfoAllocator();
......@@ -824,27 +826,28 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {
824826 if (@hasDecl(root, "os") and @hasDecl(root.os, "debug") and @hasDecl(root.os.debug, "openSelfDebugInfo")) {
825827 return noasync root.os.debug.openSelfDebugInfo(allocator);
826828 }
827 if (builtin.os == .windows) {
828 return noasync openSelfDebugInfoWindows(allocator);
829 }
830829 if (comptime std.Target.current.isDarwin()) {
831830 return noasync openSelfDebugInfoMacOs(allocator);
832831 }
833 if (builtin.os == .linux) {
832 if (builtin.os == .linux or builtin.os == .windows) {
834833 _ = try allocator.create(u32);
835834 return DebugInfo.init(allocator);
836835 }
837836 return noasync openSelfDebugInfoPosix(allocator);
838837}
839838
840fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
839fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !ObjectDebugInfo {
841840 const self_file = try fs.openSelfExe();
842841 defer self_file.close();
842 return openCoffDebugInfo(allocator, self_file);
843}
843844
845fn openCoffDebugInfo(allocator: *mem.Allocator, self_file: fs.File) !ObjectDebugInfo {
844846 const coff_obj = try allocator.create(coff.Coff);
845847 coff_obj.* = coff.Coff.init(allocator, self_file);
846848
847 var di = DebugInfo{
849 var di = ObjectDebugInfo{
850 .base_address = 0,
848851 .coff = coff_obj,
849852 .pdb = undefined,
850853 .sect_contribs = undefined,
......@@ -1202,24 +1205,97 @@ const MachoSymbol = struct {
12021205
12031206pub const DebugInfo = struct {
12041207 allocator: *mem.Allocator,
1205 address_map: std.StringHashMap(*ObjectDebugInfo),
1208 address_map: std.AutoHashMap(usize, *ObjectDebugInfo),
12061209
12071210 pub fn init(allocator: *mem.Allocator) DebugInfo {
12081211 return DebugInfo{
12091212 .allocator = allocator,
1210 .address_map = std.StringHashMap(*ObjectDebugInfo).init(allocator),
1213 .address_map = std.AutoHashMap(usize, *ObjectDebugInfo).init(allocator),
12111214 };
12121215 }
12131216
12141217 pub fn deinit(self: *DebugInfo) void {
1218 // XXX Free the values
12151219 self.address_map.deinit();
12161220 }
12171221
12181222 pub fn lookupByAddress(self: *DebugInfo, address: usize) !*ObjectDebugInfo {
1219 const obj_di = try self.lookupModuleDl(address);
1223 const obj_di = if (builtin.os == .windows)
1224 try self.lookupModuleWin32(address)
1225 else
1226 try self.lookupModuleDl(address);
12201227 return obj_di;
12211228 }
12221229
1230 fn lookupModuleWin32(self: *DebugInfo, address: usize) !*ObjectDebugInfo {
1231 const process_handle = windows.kernel32.GetCurrentProcess();
1232
1233 var modules: [32]windows.HMODULE = undefined;
1234 var modules_needed: windows.DWORD = undefined;
1235 // XXX Ask for the number of modules by passing size zero
1236 if (windows.kernel32.K32EnumProcessModules(
1237 process_handle,
1238 @ptrCast([*]windows.HMODULE, &modules),
1239 @sizeOf(@TypeOf(modules)),
1240 &modules_needed,
1241 ) == 0)
1242 return error.DebugInfoNotFound;
1243
1244 for (modules[0..modules_needed]) |module| {
1245 var info: windows.MODULEINFO = undefined;
1246 if (windows.kernel32.K32GetModuleInformation(
1247 process_handle,
1248 module,
1249 &info,
1250 @sizeOf(@TypeOf(info)),
1251 ) == 0)
1252 return error.DebugInfoNotFound;
1253
1254 const seg_start = @ptrToInt(info.lpBaseOfDll);
1255 const seg_end = seg_start + info.SizeOfImage;
1256
1257 if (address >= seg_start and address < seg_end) {
1258 var name_buffer: [windows.PATH_MAX_WIDE]u16 = [_]u16{0} ** windows.PATH_MAX_WIDE;
1259 // XXX Use W variant
1260 const len = windows.kernel32.K32GetModuleFileNameExW(
1261 process_handle,
1262 module,
1263 @ptrCast(windows.LPWSTR, &name_buffer),
1264 @sizeOf(@TypeOf(name_buffer)) / @sizeOf(u16),
1265 );
1266 assert(len > 0);
1267 const name_slice = mem.toSlice(u16, name_buffer[0..:0]);
1268 warn("slice len {}\n", .{name_slice.len});
1269
1270 const x = try std.unicode.utf16leToUtf8Alloc(self.allocator, name_buffer[0..]);
1271 warn("ask for {s} len {}\n", .{ x, name_slice.len });
1272 self.allocator.free(x);
1273
1274 if (self.address_map.getValue(seg_start)) |obj_di| {
1275 warn("cache hit!\n", .{});
1276 return obj_di;
1277 }
1278
1279 warn("loading?\n", .{});
1280 const file_obj = try fs.openFileAbsoluteW(name_slice, .{});
1281 errdefer file_obj.close();
1282 warn("loaded!\n", .{});
1283
1284 const obj_di = try self.allocator.create(ObjectDebugInfo);
1285 errdefer self.allocator.destroy(obj_di);
1286
1287 try self.address_map.putNoClobber(seg_start, obj_di);
1288
1289 obj_di.* = try openCoffDebugInfo(self.allocator, file_obj);
1290 obj_di.base_address = seg_start;
1291
1292 return obj_di;
1293 }
1294 }
1295
1296 return error.DebugInfoNotFound;
1297 }
1298
12231299 fn lookupModuleDl(self: *DebugInfo, address: usize) !*ObjectDebugInfo {
12241300 var ctx = DIPContext{ .address = address };
12251301
......@@ -1231,7 +1307,7 @@ pub const DebugInfo = struct {
12311307
12321308 warn("found in \"{s}\"\n", .{ctx.name});
12331309
1234 if (self.address_map.getValue(ctx.name)) |obj_di| {
1310 if (self.address_map.getValue(ctx.base_address)) |obj_di| {
12351311 warn("cache hit!\n", .{});
12361312 return obj_di;
12371313 }
......@@ -1257,7 +1333,7 @@ pub const DebugInfo = struct {
12571333 const obj_di = try self.allocator.create(ObjectDebugInfo);
12581334 errdefer self.allocator.destroy(obj_di);
12591335
1260 try self.address_map.putNoClobber(ctx.name, obj_di);
1336 try self.address_map.putNoClobber(ctx.base_address, obj_di);
12611337
12621338 obj_di.* = .{
12631339 .dwarf = try openElfDebugInfo(self.allocator, exe_mmap),
......@@ -1289,7 +1365,7 @@ fn dl_iterate_phdr_callback(info: *os.dl_phdr_info, size: usize, context: ?*DIPC
12891365 const seg_start = info.dlpi_addr + phdr.p_vaddr;
12901366 const seg_end = seg_start + phdr.p_memsz;
12911367
1292 if (address > seg_start and address <= seg_end) {
1368 if (address >= seg_start and address < seg_end) {
12931369 // Android libc uses NULL instead of an empty string to mark the
12941370 // main program
12951371 context.?.name = if (info.dlpi_name) |dlpi_name|
......@@ -1324,6 +1400,7 @@ pub const ObjectDebugInfo = switch (builtin.os) {
13241400 }
13251401 },
13261402 .uefi, .windows => struct {
1403 base_address: usize,
13271404 pdb: pdb.Pdb,
13281405 coff: *coff.Coff,
13291406 sect_contribs: []pdb.SectionContribEntry,
lib/std/fs.zig+2
......@@ -859,6 +859,8 @@ pub const Dir = struct {
859859 null,
860860 0,
861861 );
862 std.debug.warn("here? rc {x}\n", .{rc});
863
862864 switch (rc) {
863865 .SUCCESS => return result,
864866 .OBJECT_NAME_INVALID => unreachable,