-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Keeping 'stack_pointer` in sync with frame->stacktop is possibly too tricky #94666
Comments
Some possible "solutions":
|
For starters, it would be nice to properly define the invariant. There are obviously cases when |
The invariant is well defined. https://github.com/python/cpython/blob/main/Python/ceval.c#L1706 explains why the in-memory stack offset is made invalid when the stack pointer is held in a register.
When are they out of sync? |
I should say that the stack pointer is (along with the instruction pointer) the hottest variable int the entire VM and needs to be in a register. No harm in adding more asserts, though. |
See #94215 (and my comment at #94215 (comment)). |
Where in the code? They can only be out of sync when both are valid and reachable. |
Looking at the code, it appears that we don't set |
While considering the situation of gh-94215, I realized there is a broader concern worth discussing, of which that issue is a specific instance. FWIW, this isn't some massive, pervasive, nor high-priority problem that needs immediate attention. It is worth consideration at some point, though, as it's bitten us already and I expect it will bite us again.
Context:
In the eval loop (in ceval.c), we copy some interpreter/thread/frame state into local variables, to reduce overhead a little. Of these variables, several get modified during execution. One of them,
stack_pointer
, must be kept in sync with theframe->stacktop
, which can be modified via_PyFrame_SetStackPointer()
,_PyFrame_StackPop()
, and_PyFrame_StackPush()
. We passstack_pointer
in various calls (e.g. vectorcall) throughout the eval loop, so it is important that it stay in sync, at least at the points where we use it. (I covered this a bit more in the other issue.)The Concern:
From where I'm at, it's hard to have a lot of confidence that we are preserving the invaraiant (that
stack_pointer
is properly in sync with the frame state) in all cases. There doesn't seem to be any structural mechanism by which we get guarantees (relative to use of_PyFrame_SetStackPointer()
, etc.). Instead it seems like knowing when to synchronizestack_pointer
, and when we can avoid unnecessary synchronization, currently requires deep knowledge of a lot of pieces.Consequently, it seems like it is relatively easy to break the invariant accidentally. The fact that it happened to someone as knowledgeable as @markshannon really says a lot.
Am I out of touch here? If not, is it worth doing something about all that?
CC @iritkatriel @tiran @markshannon @pablogsal
The text was updated successfully, but these errors were encountered: