<div dir="ltr"><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Feb 27, 2024 at 1:07 PM Adrian Prantl <<a href="mailto:aprantl@apple.com">aprantl@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><br id="m_3074233907466722332lineBreakAtBeginningOfMessage"><div><br><blockquote type="cite"><div>On Feb 27, 2024, at 10:32 AM, Kyle Huey <<a href="mailto:khuey@pernos.co" target="_blank">khuey@pernos.co</a>> wrote:</div><br><div><div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Feb 21, 2024 at 9:12 AM Adrian Prantl <<a href="mailto:aprantl@apple.com" target="_blank">aprantl@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Can you clarify what kind of information you are interested in? Are you talking about representing variables inside of coroutines, function pointers to coroutines, linetables for coroutines, ...?<br>
<br>
LLDB's Swift plugin for example supports Swift async functions (which are effectively coroutines) but does so without adding any new extensions to DWARF. Here's a recent talk from last year's LLVM dev meeting on that topic: <a href="https://www.youtube.com/watch?v=g4fei6Vl7o8" rel="noreferrer" target="_blank">https://www.youtube.om/watch?v=g4fei6Vl7o8</a><br></blockquote><div><br></div><div>The async control flow parts of this (backtraces and stepping) are what I am particularly interested in. Variables seem straightforward since DWARF location expressions are already generic enough to let you point to heap allocated storage for variables that survive across yield points. Your talk is a good demo of the behavior I'd like to achieve (for Rust specifically). A few technical questions:</div><div><br></div><div>How do you "identify" a particular chain of funclet invocations that go together? I assume this is done based on the pointer identity of the async_context.</div></div></div></div></blockquote><div><br></div><div>Each async_context has a continuation pointer pointing to the next funclet that is going to be executed when the current coroutine returns.</div></div></div></blockquote><div><br></div><div>Sure, but if you have multiple async_contexts executing the same sequence of funclets you have to condition stopping at the next funclet on having the right async_context, no?</div><div><br></div><div>Put another way (forgive my pseudo code), if you have</div><div><br></div><div>function silly_print() {</div><div>    delay = rand();<br></div><div>    // Point 1<br></div><div>    async_sleep(delay).await;</div><div>    // Point 2<br></div><div>    printf("Hello" );<br></div><div>}</div><div><br></div><div>function do_stuff() {</div><div>    runtime.async_dispatch(silly_print());</div><div>    runtime.async_dispatch(silly_print());</div><div>}</div><div><br></div>When stepping from point 1 to point 2, the breakpoint on the post-await funclet at point 2 has to be conditional on being on the async_context being the same async_context the debugger was using at point 1, right? And then you have to be able to determine what the "same async_context" is.</div><div class="gmail_quote"><br></div><div class="gmail_quote">- Kyle<br></div><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div>And the logic to understand what the async_context is and where it's found at function entry points is hardcoded into the Swift plugin?</div></div></div></div></blockquote><div><br></div><div>Yes, there is a Swift-specific unwinder plugin in LLDB that does this. There is also a custom stepping plan there.</div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div><br></div><div>How do you handle pointer reuse on async_contexts?</div></div></div></div></blockquote><div><br></div><div>If I'm understanding the question correctly: there is a heap async_context object for every continuation that is on the schedule at any time. I don't think we can prevent a later continuation to be allocated in the same place as a previous one, but since they can never appear at the same time, this also isn't a problem.</div><div><br></div><div>-- adrian</div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div><br></div><div>- Kyle<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-- adrian<br>
<br>
<br>
<br>
<br>
<br>
> On Feb 20, 2024, at 11:47 AM, Kyle Huey via Dwarf-discuss <<a href="mailto:dwarf-discuss@lists.dwarfstd.org" target="_blank">dwarf-discuss@lists.dwarfstd.org</a>> wrote:<br>
> <br>
> Has anyone proposed or discussed DWARF structures to represent coroutines or similar constructs? I skimmed the open issues list and didn't see anything relevant.<br>
> <br>
> - Kyle<br>
<br>
</blockquote></div></div>
</div></blockquote></div><br></div></blockquote></div></div>