Skip to content

Commit e14dc8e

Browse files
committed
ReuseFRAME_OWNED_BY_INTERPRETER
1 parent 3d9c294 commit e14dc8e

File tree

6 files changed

+6
-12
lines changed

6 files changed

+6
-12
lines changed

Include/internal/pycore_interpframe_structs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ enum _frameowner {
2424
FRAME_OWNED_BY_GENERATOR = 1,
2525
FRAME_OWNED_BY_FRAME_OBJECT = 2,
2626
FRAME_OWNED_BY_INTERPRETER = 3,
27-
FRAME_OWNED_BY_THREAD_STATE = 4, /* Sentinel base frame in thread state */
2827
};
2928

3029
struct _PyInterpreterFrame {

InternalDocs/frames.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ instruction which cleans up the shim frame and returns.
116116
Each thread state contains an embedded `_PyInterpreterFrame` called the "base frame"
117117
that serves as a sentinel at the bottom of the frame stack. This frame is allocated
118118
in `_PyThreadStateImpl` (the internal extension of `PyThreadState`) and initialized
119-
when the thread state is created. The `owner` field is set to `FRAME_OWNED_BY_THREAD_STATE`.
119+
when the thread state is created. The `owner` field is set to `FRAME_OWNED_BY_INTERPRETER`.
120120

121121
External profilers and sampling tools can validate that they have successfully unwound
122122
the complete call stack by checking that the frame chain terminates at the base frame.
@@ -135,7 +135,7 @@ See the initialization in `new_threadstate()` in [Python/pystate.c](../Python/py
135135

136136
External profilers should read `tstate->base_frame` before walking the stack, then
137137
walk from `tstate->current_frame` following `frame->previous` pointers until reaching
138-
a frame with `owner == FRAME_OWNED_BY_THREAD_STATE`. After the walk, verify that the
138+
a frame with `owner == FRAME_OWNED_BY_INTERPRETER`. After the walk, verify that the
139139
last frame address matches `base_frame`. If not, discard the sample as incomplete
140140
since the frame chain may have been in an inconsistent state due to concurrent updates.
141141

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Add incomplete sample detection to prevent corrupted profiling data. Each
22
thread state now contains an embedded base frame (sentinel at the bottom of
3-
the frame stack) with owner type ``FRAME_OWNED_BY_THREAD_STATE``. The profiler
3+
the frame stack) with owner type ``FRAME_OWNED_BY_INTERPRETER``. The profiler
44
validates that stack unwinding terminates at this sentinel frame. Samples that
55
fail to reach the base frame (due to race conditions, memory corruption, or
66
other errors) are now rejected rather than being included as spurious data.

Modules/_remote_debugging/frames.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,7 @@ is_frame_valid(
156156

157157
char owner = GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner);
158158
if (owner == FRAME_OWNED_BY_INTERPRETER) {
159-
return 0; // C frame
160-
}
161-
162-
if (owner == FRAME_OWNED_BY_THREAD_STATE) {
163-
return 0; // Sentinel base frame - end of stack
159+
return 0; // C frame or sentinel base frame
164160
}
165161

166162
if (owner != FRAME_OWNED_BY_GENERATOR && owner != FRAME_OWNED_BY_THREAD) {

Python/pystate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ init_threadstate(_PyThreadStateImpl *_tstate,
14931493
_tstate->base_frame.instr_ptr = NULL;
14941494
_tstate->base_frame.stackpointer = _tstate->base_frame.localsplus;
14951495
_tstate->base_frame.return_offset = 0;
1496-
_tstate->base_frame.owner = FRAME_OWNED_BY_THREAD_STATE;
1496+
_tstate->base_frame.owner = FRAME_OWNED_BY_INTERPRETER;
14971497
_tstate->base_frame.visited = 0;
14981498
#ifdef Py_DEBUG
14991499
_tstate->base_frame.lltrace = 0;

Python/traceback.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,8 +1035,7 @@ _Py_DumpWideString(int fd, wchar_t *str)
10351035
static int
10361036
dump_frame(int fd, _PyInterpreterFrame *frame)
10371037
{
1038-
if (frame->owner == FRAME_OWNED_BY_INTERPRETER ||
1039-
frame->owner == FRAME_OWNED_BY_THREAD_STATE) {
1038+
if (frame->owner == FRAME_OWNED_BY_INTERPRETER) {
10401039
/* Ignore trampoline frames and base frame sentinel */
10411040
return 0;
10421041
}

0 commit comments

Comments
 (0)