authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-18 19:03:31+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-20 19:41:29+01:00
logce2efbdca6f1bf8a1ac01c379cb90990a2ea4e78
tree93be4b985a8797c6ca21d057c91a022da5035dfa
parentd5b583008ad477c292db4f783072605f5d28f843

Correctly count all the loaded modules on Windows


1 files changed, 28 insertions(+), 10 deletions(-)

lib/std/debug.zig+28-10
......@@ -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, 1 => {
251 0 => {
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 2 => {
259 1 => {
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.
......@@ -1289,19 +1289,37 @@ pub const DebugInfo = struct {
12891289 fn lookupModuleWin32(self: *DebugInfo, address: usize) !*ObjectDebugInfo {
12901290 const process_handle = windows.kernel32.GetCurrentProcess();
12911291
1292 var modules: [32]windows.HMODULE = undefined;
1293 var modules_needed: windows.DWORD = undefined;
1294 // TODO: Ask for the number of modules by passing size zero, 32 ought to
1295 // be enough for everyone in the meanwhile
1292 // Find how many modules are actually loaded
1293 var dummy: windows.HMODULE = undefined;
1294 var bytes_needed: windows.DWORD = undefined;
12961295 if (windows.kernel32.K32EnumProcessModules(
12971296 process_handle,
1298 @ptrCast([*]windows.HMODULE, &modules),
1299 @sizeOf(@TypeOf(modules)),
1300 &modules_needed,
1297 @ptrCast([*]windows.HMODULE, &dummy),
1298 0,
1299 &bytes_needed,
1300 ) == 0)
1301 return error.DebugInfoNotFound;
1302
1303 const needed_modules = bytes_needed / @sizeOf(windows.HMODULE);
1304
1305 // Fetch the complete module list
1306 var modules = try self.allocator.alloc(windows.HMODULE, needed_modules);
1307 defer self.allocator.free(modules);
1308 if (windows.kernel32.K32EnumProcessModules(
1309 process_handle,
1310 modules.ptr,
1311 try math.cast(windows.DWORD, modules.len * @sizeOf(windows.HMODULE)),
1312 &bytes_needed,
13011313 ) == 0)
13021314 return error.DebugInfoNotFound;
13031315
1304 for (modules[0..modules_needed]) |module| {
1316 // There's an unavoidable TOCTOU problem here, the module list may have
1317 // changed between the two EnumProcessModules call.
1318 // Pick the smallest amount of elements to avoid processing garbage.
1319 const needed_modules_after = bytes_needed / @sizeOf(windows.HMODULE);
1320 const loaded_modules = math.min(needed_modules, needed_modules_after);
1321
1322 for (modules[0..loaded_modules]) |module| {
13051323 var info: windows.MODULEINFO = undefined;
13061324 if (windows.kernel32.K32GetModuleInformation(
13071325 process_handle,