| ... | @@ -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 | } |
| 249 | | 249 | |
| 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 case | 260 | // 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 thread | 261 | // 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(); |
| 1291 | | 1291 | |
| 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 to | 1294 | 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; |
| 1303 | | 1315 | |
| 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, |