Skip to content

Can't access full stack of suspended greenlet on 3.12 #388

Closed
@oremanj

Description

@oremanj

The gr_frame attribute refers to the innermost frame (the frame that called switch()), but its f_back attribute points nowhere.

% python3.12
Python 3.12.0 (v3.12.0:0fb18b02c8, Oct  2 2023, 09:45:56) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import greenlet
>>> def inner(): greenlet.getcurrent().parent.switch(42)
...
>>> def outer(): inner()
...
>>> gr = greenlet.greenlet(outer)
>>> gr.switch()
42
>>> gr.gr_frame
<frame at 0x10438b7e0, file '<stdin>', line 1, code inner>
>>> gr.gr_frame.f_back
>>> greenlet.__version__
'3.0.1'
>>>

On 3.11 I see instead:

>>> gr.gr_frame
<frame at 0x7feb24db2700, file '<stdin>', line 1, code inner>
>>> gr.gr_frame.f_back
<frame at 0x7feb24db2660, file '<stdin>', line 1, code outer>
>>> gr.gr_frame.f_back.f_back
>>>

which is what I would expect from the documentation. This looks related to some logic in TPythonState.cpp that moves the previous ptr into greenlet-local storage when suspending:

    if (frame) {
        this->_prev_frame = frame->f_frame->previous;
        frame->f_frame->previous = nullptr;
    }

How is greenlet introspection supposed to work on 3.12?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions