gh-138122: Don't sample partial frame chains (#141912)

This commit is contained in:
Pablo Galindo Salgado 2025-12-07 15:53:48 +00:00 committed by GitHub
parent c5b37228af
commit d6d850df89
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 135 additions and 105 deletions

View file

@ -1482,7 +1482,31 @@ init_threadstate(_PyThreadStateImpl *_tstate,
// This is cleared when PyGILState_Ensure() creates the thread state.
tstate->gilstate_counter = 1;
tstate->current_frame = NULL;
// Initialize the embedded base frame - sentinel at the bottom of the frame stack
_tstate->base_frame.previous = NULL;
_tstate->base_frame.f_executable = PyStackRef_None;
_tstate->base_frame.f_funcobj = PyStackRef_NULL;
_tstate->base_frame.f_globals = NULL;
_tstate->base_frame.f_builtins = NULL;
_tstate->base_frame.f_locals = NULL;
_tstate->base_frame.frame_obj = NULL;
_tstate->base_frame.instr_ptr = NULL;
_tstate->base_frame.stackpointer = _tstate->base_frame.localsplus;
_tstate->base_frame.return_offset = 0;
_tstate->base_frame.owner = FRAME_OWNED_BY_INTERPRETER;
_tstate->base_frame.visited = 0;
#ifdef Py_DEBUG
_tstate->base_frame.lltrace = 0;
#endif
#ifdef Py_GIL_DISABLED
_tstate->base_frame.tlbc_index = 0;
#endif
_tstate->base_frame.localsplus[0] = PyStackRef_NULL;
// current_frame starts pointing to the base frame
tstate->current_frame = &_tstate->base_frame;
// base_frame pointer for profilers to validate stack unwinding
tstate->base_frame = &_tstate->base_frame;
tstate->datastack_chunk = NULL;
tstate->datastack_top = NULL;
tstate->datastack_limit = NULL;
@ -1660,7 +1684,7 @@ PyThreadState_Clear(PyThreadState *tstate)
int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
if (verbose && tstate->current_frame != NULL) {
if (verbose && tstate->current_frame != tstate->base_frame) {
/* bpo-20526: After the main thread calls
_PyInterpreterState_SetFinalizing() in Py_FinalizeEx()
(or in Py_EndInterpreter() for subinterpreters),