mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Stabilize Windows all-thread traceback reads with stop-the-world (#9092)
Use the existing normal dump_traceback stop-the-world path on Windows before traversing raw interpreter frames. Preserve registry-lock release before resuming threads. Signal and watchdog paths are unchanged. Assisted-by: OpenAI Codex:model identifier unavailable Co-authored-by: dot <dot@youknowone.org>
This commit is contained in:
1 parent
8b66b7c48f
commit
8f47ced2c7
1 file changed
+2
-45
@@ -252,10 +252,10 @@ mod decl {
|
||||
#[cfg(any(unix, windows))]
|
||||
fn dump_all_threads(fd: i32, vm: &VirtualMachine) {
|
||||
// Get all threads' frame stacks from the shared registry
|
||||
// unix: stop-the-world so every other thread is parked at a safepoint
|
||||
// Stop the world so every other thread is parked at a safepoint
|
||||
// and its frame chain is quiescent and alive while we walk it (matches
|
||||
// faulthandler.dump_traceback running with the GIL held).
|
||||
#[cfg(all(unix, feature = "threading"))]
|
||||
#[cfg(feature = "threading")]
|
||||
{
|
||||
use core::sync::atomic::Ordering;
|
||||
let current_tid = rustpython_vm::stdlib::_thread::get_ident();
|
||||
@@ -302,49 +302,6 @@ mod decl {
|
||||
dump_live_frames(fd);
|
||||
}
|
||||
|
||||
#[cfg(all(not(unix), feature = "threading"))]
|
||||
{
|
||||
let current_tid = rustpython_vm::stdlib::_thread::get_ident();
|
||||
let registry = vm.state.thread_frames.lock();
|
||||
|
||||
// Dump non-current threads using top_iframe, which includes
|
||||
// both FrameObject and stack-allocated frames.
|
||||
#[expect(
|
||||
clippy::iter_over_hash_type,
|
||||
reason = "Iteration order doesn't matter here"
|
||||
)]
|
||||
for (&tid, slot) in registry.iter() {
|
||||
if tid == current_tid {
|
||||
continue;
|
||||
}
|
||||
|
||||
let iframe_ptr = slot.top_iframe.load(core::sync::atomic::Ordering::Relaxed)
|
||||
as *const rustpython_vm::frame::InterpreterFrame;
|
||||
write_thread_id(fd, tid, false);
|
||||
if iframe_ptr.is_null() {
|
||||
puts(fd, " <no Python frame>\n");
|
||||
} else {
|
||||
let mut cur = iframe_ptr;
|
||||
let mut depth = 0;
|
||||
while !cur.is_null() && depth < 100 {
|
||||
let iframe = unsafe { &*cur };
|
||||
dump_iframe(fd, iframe);
|
||||
depth += 1;
|
||||
cur = iframe.previous();
|
||||
}
|
||||
if depth >= 100 && !cur.is_null() {
|
||||
puts(fd, " ...\n");
|
||||
}
|
||||
}
|
||||
puts(fd, "\n");
|
||||
}
|
||||
|
||||
// Now dump current thread from its live frame chain
|
||||
// (includes stack-allocated iframes without FrameObject).
|
||||
write_thread_id(fd, current_tid, true);
|
||||
dump_live_frames(fd);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "threading"))]
|
||||
{
|
||||
let _ = vm;
|
||||
|
||||
Reference in new issue
Block a user