Skip to content

Trace the bodies of async functions and async generators - #2109

Merged
slozier merged 4 commits into
IronLanguages:mainfrom
BCSharp:async-trace
Oct 23, 2026
Merged

slozier merged 4 commits into
IronLanguages:mainfrom
BCSharp:async-trace

Conversation

@BCSharp

@BCSharp BCSharp commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

This PR uses the DLR's async-body tracing (IronLanguages/dlr#369): the tracing variant of an async function hands its Async/AsyncEnumerable node the function's debug context, so the body is traced while the coroutine runs. Creating the coroutine is no longer traced, as in CPython.

Also, some smaller fixes:

  • The body's entry point is at the start of the function again, and an async def now starts at its async keyword, so the 'call' location (and ast col_offset) match CPython.
  • Setting f_lineno on an async body frame raises ValueError (jumping is not supported there yet).
  • Fixes IronPython's GeneratorRewriter, like the DLR's in 369: an exception handler containing a yield that left its loop iteration early (continue/break) ran again after a later pass through the try that raised nothing. This affected sync generators, and async functions on .NET Framework as well.

The DLR submodule is updated to the one with the async-body tracing implementation.
Fixes #2065, though for the full debugging support, f_locals and jumps in an async body frame are still needed.

@slozier

slozier commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

The CI failure is probably unrelated:

import sys
def f():
    class Boom(Exception): pass

sys.settrace(lambda *a: None)
f() 
sys.settrace(None)
f() # TypeError: Unable to cast ... Func`2[PythonFunction,Object] ... Func`2[CodeContext,CodeContext]

@BCSharp

BCSharp commented Oct 22, 2026

Copy link
Copy Markdown
Member Author

I cannot reproduce any test failure (on Windows , using .NET 8). Also your sample code runs fine on my Windows system. In the log I also noticed something suspicious: test_asyncgen was skipped for an unknown reason. It should run under .NET 8, and normally does.

I'll try to rerun the CI check.

@slozier

slozier commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Also your sample code runs fine on my Windows system

Interesting, for me this fails the majority of the time everywhere I tried (windows, mac, linux).

test_asyncgen was skipped for an unknown reason

it's marked as ignore...

[IronPython.test_asyncgen]
Ignore=true
RunCondition='$(FRAMEWORK)' <> '.NETFramework,Version=v4.6.2'
Reason=Requires IAsyncEnumerable & IAsyncDisposable

@BCSharp

BCSharp commented Oct 22, 2026

Copy link
Copy Markdown
Member Author

Interesting, for me this fails the majority of the time everywhere I tried (windows, mac, linux).

I was finally able to reproduce it. It happens occasionally on my systems, which suggests a race condition of some sort. I was able to trigger it on both net8.0 and net10.0. But more interestingly, it can happen also on main, so the bug predates this PR. I will look into it in a separate PR.

it's marked as ignore...

That's wrong — it is supposed to be ignored only on .NET Framework/Mono. I will patch the .ini file here.

@slozier slozier left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good to me!

Comment thread src/core/IronPython/Runtime/FunctionCode.cs Outdated
@slozier
slozier merged commit a48fa86 into IronLanguages:main Oct 23, 2026
55 of 56 checks passed
@BCSharp
BCSharp deleted the async-trace branch October 24, 2026 00:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Debug/trace info not generated for DLR-based coroutines and async generators

2 participants