Skip to content

Commit f0e6be7

Browse files
DinoVmeta-codesync[bot]
authored andcommitted
Protect against deadlocks in stack walk API
Summary: This is just adding some extra defense to the stack walk API. alexmalyshev asked "What happens if a second sampling thread appears and sends another SIGUSR1?" It's actually the callers responsibility to protect this with a lock (which we rely on either the GIL or the FreeThreadedJITEntrypointGuard to do so). But there's an additional concern about if someone sent our walking thread a signal while we were trying to walk the stack. In that case the walking thread that sent us the signal could depend upon a resource owned by the thread that we are trying to walk. That'd result in a deadlock. So now the sampled thread will give up if the sampling thread fails to walk it in a reasonable amount of time. Reviewed By: alexmalyshev Differential Revision: D116388968 fbshipit-source-id: 8fa581c5fb57081c3f0bad3cdd74d25f4900fa83
1 parent a78e01c commit f0e6be7

4 files changed

Lines changed: 1494 additions & 97 deletions

File tree

cinderx/Jit/frame.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,12 @@ const void** getIPStackAddr(_PyInterpreterFrame* frame, int) {
160160

161161
FreeThreadedJITEntrypointGuard guard;
162162
StackWalk walker;
163-
walker.walk(owner, visit);
163+
if (walker.walk(owner, visit) != WalkResult::Completed) {
164+
// A walk that did not finish leaves nothing worth keeping. It either never
165+
// started, or the owner stopped waiting for us part way through - and an
166+
// address out of a stack that has resumed is not one to hand back.
167+
return nullptr;
168+
}
164169
return result;
165170
}
166171

0 commit comments

Comments
 (0)