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...@@ -248,7 +248,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c
248 }248 }
249249
250 switch (@atomicRmw(u8, &panicking, .Add, 1, .SeqCst)) {250 switch (@atomicRmw(u8, &panicking, .Add, 1, .SeqCst)) {
251 0, 1 => {251 0 => {
252 const stderr = getStderrStream();252 const stderr = getStderrStream();
253 noasync stderr.print(format ++ "\n", args) catch os.abort();253 noasync stderr.print(format ++ "\n", args) catch os.abort();
254 if (trace) |t| {254 if (trace) |t| {
...@@ -256,7 +256,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c...@@ -256,7 +256,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c
256 }256 }
257 dumpCurrentStackTrace(first_trace_addr);257 dumpCurrentStackTrace(first_trace_addr);
258 },258 },
259 2 => {259 1 => {
260 // TODO detect if a different thread caused the panic, because in that case260 // TODO detect if a different thread caused the panic, because in that case
261 // we would want to return here instead of calling abort, so that the thread261 // we would want to return here instead of calling abort, so that the thread
262 // which first called panic can finish printing a stack trace.262 // which first called panic can finish printing a stack trace.
...@@ -1289,19 +1289,37 @@ pub const DebugInfo = struct {...@@ -1289,19 +1289,37 @@ pub const DebugInfo = struct {
1289 fn lookupModuleWin32(self: *DebugInfo, address: usize) !*ObjectDebugInfo {1289 fn lookupModuleWin32(self: *DebugInfo, address: usize) !*ObjectDebugInfo {
1290 const process_handle = windows.kernel32.GetCurrentProcess();1290 const process_handle = windows.kernel32.GetCurrentProcess();
12911291
1292 var modules: [32]windows.HMODULE = undefined;1292 // Find how many modules are actually loaded
1293 var modules_needed: windows.DWORD = undefined;1293 var dummy: windows.HMODULE = undefined;
1294 // TODO: Ask for the number of modules by passing size zero, 32 ought to1294 var bytes_needed: windows.DWORD = undefined;
1295 // be enough for everyone in the meanwhile
1296 if (windows.kernel32.K32EnumProcessModules(1295 if (windows.kernel32.K32EnumProcessModules(
1297 process_handle,1296 process_handle,
1298 @ptrCast([*]windows.HMODULE, &modules),1297 @ptrCast([*]windows.HMODULE, &dummy),
1299 @sizeOf(@TypeOf(modules)),1298 0,
1300 &modules_needed,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,
1301 ) == 0)1313 ) == 0)
1302 return error.DebugInfoNotFound;1314 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| {
1305 var info: windows.MODULEINFO = undefined;1323 var info: windows.MODULEINFO = undefined;
1306 if (windows.kernel32.K32GetModuleInformation(1324 if (windows.kernel32.K32GetModuleInformation(
1307 process_handle,1325 process_handle,