-
Notifications
You must be signed in to change notification settings - Fork 246
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
Change in profiler behaviour in CPython 3.10 #256
Comments
Thanks for the report! This is an issue with how greenlet is handling python/cpython#25276 from 3.10 beta1+. A fix that works (defined as "3.10rc1 produces the same output as 3.9") is to change ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
modified: src/greenlet/greenlet.c
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -922,6 +923,7 @@ green_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
((PyGreenlet*)o)->parent = ts_current;
#if GREENLET_USE_CFRAME
((PyGreenlet*)o)->cframe = &PyThreadState_GET()->root_cframe;
+ ((PyGreenlet*)o)->cframe->use_tracing = PyThreadState_GET()->cframe->use_tracing;
#endif
}
return o; Possibly that should be the This does clarify that we could use some better tests of our interaction with tracing events. |
Yeah, so a big no on both of those. The The problem with the proposed solution above is that it boils down to essentially That leaves us either creating our own new |
The cframe member was always being initialized from the PyThreadState's root_cframe, which doesn't properly have use_tracing set, so new greenlets didn't get tracing. Here, we do exactly what CPython's ceval.c does and stack-allocate a new CFrame object in g_initialstub and copy the use_tracing value from the currently executing thread state. This seems to solve the tracing issue, but further tests are needed; none of the existing tests failed with the broken behaviour. In addition to adding an example from #256, we need to test that the use_tracing flag properly propagates up and down when a profiler is set inside a greenlet, likewise I've only been testing switch, need to test throw, and need to test several variations on calling g.run(): as a method, just a target function, an object assigned to a greenlet, etc.
4287a40 fixed the problem demonstrated in this example, but as 7eee763 demonstrates, that simple, cheap solution doesn't fix all the cases, not by a longshot. To handle those I think we may wind up having to do switch-time checks. |
Hey @jamadden, thanks! I can't say that I fully followed the solution, but I appreciate the updates :). By the way, mad props on having a library that's heavily used by 81,000 projects(!) and you're only up to 259 issues. You must be doing something right :) |
I can confirm that in the latest release of Greenlet, Python 3.10 behaviour matches previous versions 👍 |
1.1.2 (2021-09-29) ================== - Fix a potential crash due to a reference counting error when Python subclasses of ``greenlet.greenlet`` were deallocated. The crash became more common on Python 3.10; on earlier versions, silent memory corruption could result. See `issue 245 <https://github.com/python-greenlet/greenlet/issues/245>`_. Patch by fygao-wish. - Fix a leak of a list object when the last reference to a greenlet was deleted from some other thread than the one to which it belonged. For this to work correctly, you must call a greenlet API like ``getcurrent()`` before the thread owning the greenlet exits: this is a long-standing limitation that can also lead to the leak of a thread's main greenlet if not called; we hope to lift this limitation. Note that in some cases this may also fix leaks of greenlet objects themselves. See `issue 251 <https://github.com/python-greenlet/greenlet/issues/251>`_. - Python 3.10: Tracing or profiling into a spawned greenlet didn't work as expected. See `issue 256 <https://github.com/python-greenlet/greenlet/issues/256>`_, reported by Joe Rickerby. Signed-off-by: Zheng Ruoqin <zhengrq.fnst@fujitsu.com> Signed-off-by: Khem Raj <raj.khem@gmail.com>
1.1.2 (2021-09-29) ================== - Fix a potential crash due to a reference counting error when Python subclasses of ``greenlet.greenlet`` were deallocated. The crash became more common on Python 3.10; on earlier versions, silent memory corruption could result. See `issue 245 <https://github.com/python-greenlet/greenlet/issues/245>`_. Patch by fygao-wish. - Fix a leak of a list object when the last reference to a greenlet was deleted from some other thread than the one to which it belonged. For this to work correctly, you must call a greenlet API like ``getcurrent()`` before the thread owning the greenlet exits: this is a long-standing limitation that can also lead to the leak of a thread's main greenlet if not called; we hope to lift this limitation. Note that in some cases this may also fix leaks of greenlet objects themselves. See `issue 251 <https://github.com/python-greenlet/greenlet/issues/251>`_. - Python 3.10: Tracing or profiling into a spawned greenlet didn't work as expected. See `issue 256 <https://github.com/python-greenlet/greenlet/issues/256>`_, reported by Joe Rickerby. Signed-off-by: Zheng Ruoqin <zhengrq.fnst@fujitsu.com> Signed-off-by: Khem Raj <raj.khem@gmail.com>
1.1.2 (2021-09-29) ================== - Fix a potential crash due to a reference counting error when Python subclasses of ``greenlet.greenlet`` were deallocated. The crash became more common on Python 3.10; on earlier versions, silent memory corruption could result. See `issue 245 <https://github.com/python-greenlet/greenlet/issues/245>`_. Patch by fygao-wish. - Fix a leak of a list object when the last reference to a greenlet was deleted from some other thread than the one to which it belonged. For this to work correctly, you must call a greenlet API like ``getcurrent()`` before the thread owning the greenlet exits: this is a long-standing limitation that can also lead to the leak of a thread's main greenlet if not called; we hope to lift this limitation. Note that in some cases this may also fix leaks of greenlet objects themselves. See `issue 251 <https://github.com/python-greenlet/greenlet/issues/251>`_. - Python 3.10: Tracing or profiling into a spawned greenlet didn't work as expected. See `issue 256 <https://github.com/python-greenlet/greenlet/issues/256>`_, reported by Joe Rickerby. Signed-off-by: Zheng Ruoqin <zhengrq.fnst@fujitsu.com> Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Trevor Gamblin <trevor.gamblin@windriver.com>
1.1.2 (2021-09-29) ================== - Fix a potential crash due to a reference counting error when Python subclasses of ``greenlet.greenlet`` were deallocated. The crash became more common on Python 3.10; on earlier versions, silent memory corruption could result. See `issue 245 <https://github.com/python-greenlet/greenlet/issues/245>`_. Patch by fygao-wish. - Fix a leak of a list object when the last reference to a greenlet was deleted from some other thread than the one to which it belonged. For this to work correctly, you must call a greenlet API like ``getcurrent()`` before the thread owning the greenlet exits: this is a long-standing limitation that can also lead to the leak of a thread's main greenlet if not called; we hope to lift this limitation. Note that in some cases this may also fix leaks of greenlet objects themselves. See `issue 251 <https://github.com/python-greenlet/greenlet/issues/251>`_. - Python 3.10: Tracing or profiling into a spawned greenlet didn't work as expected. See `issue 256 <https://github.com/python-greenlet/greenlet/issues/256>`_, reported by Joe Rickerby. Signed-off-by: Zheng Ruoqin <zhengrq.fnst@fujitsu.com> Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Trevor Gamblin <trevor.gamblin@windriver.com>
1.1.2 (2021-09-29) ================== - Fix a potential crash due to a reference counting error when Python subclasses of ``greenlet.greenlet`` were deallocated. The crash became more common on Python 3.10; on earlier versions, silent memory corruption could result. See `issue 245 <https://github.com/python-greenlet/greenlet/issues/245>`_. Patch by fygao-wish. - Fix a leak of a list object when the last reference to a greenlet was deleted from some other thread than the one to which it belonged. For this to work correctly, you must call a greenlet API like ``getcurrent()`` before the thread owning the greenlet exits: this is a long-standing limitation that can also lead to the leak of a thread's main greenlet if not called; we hope to lift this limitation. Note that in some cases this may also fix leaks of greenlet objects themselves. See `issue 251 <https://github.com/python-greenlet/greenlet/issues/251>`_. - Python 3.10: Tracing or profiling into a spawned greenlet didn't work as expected. See `issue 256 <https://github.com/python-greenlet/greenlet/issues/256>`_, reported by Joe Rickerby. Signed-off-by: Zheng Ruoqin <zhengrq.fnst@fujitsu.com> Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Trevor Gamblin <trevor.gamblin@windriver.com>
1.1.2 (2021-09-29) ================== - Fix a potential crash due to a reference counting error when Python subclasses of ``greenlet.greenlet`` were deallocated. The crash became more common on Python 3.10; on earlier versions, silent memory corruption could result. See `issue 245 <https://github.com/python-greenlet/greenlet/issues/245>`_. Patch by fygao-wish. - Fix a leak of a list object when the last reference to a greenlet was deleted from some other thread than the one to which it belonged. For this to work correctly, you must call a greenlet API like ``getcurrent()`` before the thread owning the greenlet exits: this is a long-standing limitation that can also lead to the leak of a thread's main greenlet if not called; we hope to lift this limitation. Note that in some cases this may also fix leaks of greenlet objects themselves. See `issue 251 <https://github.com/python-greenlet/greenlet/issues/251>`_. - Python 3.10: Tracing or profiling into a spawned greenlet didn't work as expected. See `issue 256 <https://github.com/python-greenlet/greenlet/issues/256>`_, reported by Joe Rickerby. Signed-off-by: Zheng Ruoqin <zhengrq.fnst@fujitsu.com> Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Trevor Gamblin <trevor.gamblin@windriver.com>
Hello there! I noticed something in the unit tests for pyinstrument while adding CPython 3.10. Here's a script:
If you run this code on Python 3.9, you get this:
On CPython 3.10.0rc1, this is the output:
What's interesting is that on 3.10, a profiler that's started outside the greenlet doesn't get to 'see' inside the greenlet that it switches to. It sees only the
greenlet.switch
. That's a change from 3.9 and before.I was wondering if this was an expected change? It's not necessarily an issue per-se, pyinstrument doesn't officially support greenlet anyway, so I'm not complaining, just curious if this change in behaviour is likely to be permanent.
The text was updated successfully, but these errors were encountered: