Skip to content

sys._setprofileallthreads race condition #137400

Description

@colesbury

Bug report

There's a race on tstate->c_profilefunc if profiling is disable concurrently via sys._setprofileallthreads or threading.setprofile_all_threads or PyEval_SetProfileAllThreads.

staticPyObject*
call_profile_func(_PyLegacyEventHandler*self, PyObject*arg)
{
PyThreadState*tstate=_PyThreadState_GET();
if (tstate->c_profilefunc==NULL) {
Py_RETURN_NONE;
}
PyFrameObject*frame=PyEval_GetFrame();
if (frame==NULL) {
PyErr_SetString(PyExc_SystemError,
"Missing frame when calling profile function.");
returnNULL;
}
Py_INCREF(frame);
interr=tstate->c_profilefunc(tstate->c_profileobj, frame, self->event, arg);
Py_DECREF(frame);
if (err) {
returnNULL;
}
Py_RETURN_NONE;
}

Repro

importsysimportthreadingdone=threading.Event()
deffoo():
passdefmy_profile(frame, event, arg):
returnNonedefbg_thread():
whilenotdone.is_set():
foo()
foo()
foo()
foo()
foo()
foo()
foo()
foo()
foo()
foo()
defmain():
bg_threads= []
foriinrange(10):
t=threading.Thread(target=bg_thread)
t.start()
bg_threads.append(t)
foriinrange(100):
print(f"Iteration {i}")
sys._setprofileallthreads(my_profile)
sys._setprofileallthreads(None)
done.set()
fortinbg_threads:
t.join()
if__name__=="__main__":
main()

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13bugs and security fixes3.14bugs and security fixes3.15pre-release feature fixes, bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)topic-free-threadingtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions