PEP 669: Low Impact Monitoring for CPython

FWIW, I think coverage.py and CPython have progressed together to be able to efficiently measure branch coverage: Faster branch coverage measurement | Ned Batchelder

We need you to try it out though!

5 Likes

Is there a fundamental reason why an event such as PY_UNWIND is not available as a local event? The PY_RETURN event is somewhat incomplete as it doesn’t allow trapping the more general event of exiting from a function (be it with a result or with an exception). Having PY_UNWIND as a local event would make this more complete. For a more concrete use-case, one might be interested in “wrapping” around a specific function to react to when the function is entered (to report e.g. invocation arguments) and then exited (to grab either the return value or any exceptions that might have been thrown, plus the state of the frame locals).

Unwinding is part of exception handling, not normal execution. So, like RAISE, it doesn’t have a specific location in the code where it occurs.
Local events are tied to specific locations in the code, so can be instrumented.

It would be possible to generate an unwind point for functions, essentially wrapping all functions in a try-except, but it would bulk out the code object, slow down exception handling in the normal case and complicate the compiler.

These all feel like weak arguments to me

Unwinding is part of exception handling, not normal execution. So, like RAISE, it doesn’t have a specific location in the code where it occurs.

Unwinding involves the step of exiting from the current function/frame. Like when a new frame is created and pushed to the stack, its popping is also a well-defined event within the runtime. The fact that PY_START has a location within the code object to instrument is a mere accident of the implementation. It could have been implemented without any instrumentation by emitting an event as soon as the frame is created/executed.

It would be possible to generate an unwind point for functions, essentially wrapping all functions in a try-except, but it would bulk out the code object, slow down exception handling in the normal case and complicate the compiler.

I don’t think this is needed. I have drafted Make PY_UNWIND available as a local event by P403n1x87 · Pull Request #142179 · python/cpython · GitHub where I add a “local check” to monitor_unwind.

These all feel like weak arguments to me

You asked why PY_UNWIND is not available as a local event. I told you why.
I’m not arguing whether it should be a local event or not. I’m merely stating why it is that way.

The PEP was accepted over three years ago, so it is a bit late to change the PEP.

If you want to make non-trivial changes or improvements to the implementation, then opening an issue (not a PR first) on CPython is the best way to do it. As long as changes are backwards compatible we’re open to improvements. e.g. Add BRANCH_TAKEN and BRANCH_NOT_TAKEN events to sys.monitoring · Issue #122548 · python/cpython · GitHub

1 Like

Ok, thanks for clarifying. I was just trying to state the case that PY_UNWIND makes sense as a local event and gauge whether there would be any push-back in making such a change.