@@ -361,23 +361,13 @@ class ThreadPlanRunToAddressOnAsyncCtx : public ThreadPlan {
361361
362362// / Given a thread that is stopped at the start of swift_task_switch, create a
363363// / thread plan that runs to the address of the resume function.
364- static ThreadPlanSP CreateRunThroughTaskSwitchThreadPlan (Thread &thread) {
365- // The signature for `swift_task_switch` is as follows:
366- // SWIFT_CC(swiftasync)
367- // void swift_task_switch(
368- // SWIFT_ASYNC_CONTEXT AsyncContext *resumeContext,
369- // TaskContinuationFunction *resumeFunction,
370- // ExecutorRef newExecutor);
371- //
372- // The async context given as the first argument is not passed using the
373- // calling convention's first register, it's passed in the platform's async
374- // context register. This means the `resumeFunction` parameter uses the
375- // first ABI register (ex: x86-64: rdi, arm64: x0).
364+ static ThreadPlanSP
365+ CreateRunThroughTaskSwitchThreadPlan (Thread &thread,
366+ unsigned resume_fn_generic_regnum) {
376367 RegisterContextSP reg_ctx =
377368 thread.GetStackFrameAtIndex (0 )->GetRegisterContext ();
378- constexpr unsigned resume_fn_regnum = LLDB_REGNUM_GENERIC_ARG1;
379369 unsigned resume_fn_reg = reg_ctx->ConvertRegisterKindToRegisterNumber (
380- RegisterKind::eRegisterKindGeneric, resume_fn_regnum );
370+ RegisterKind::eRegisterKindGeneric, resume_fn_generic_regnum );
381371 uint64_t resume_fn_ptr = reg_ctx->ReadRegisterAsUnsigned (resume_fn_reg, 0 );
382372 if (!resume_fn_ptr)
383373 return {};
@@ -397,6 +387,29 @@ static ThreadPlanSP CreateRunThroughTaskSwitchThreadPlan(Thread &thread) {
397387 thread, resume_fn_ptr, async_ctx);
398388}
399389
390+ // / Creates a thread plan to step over swift runtime functions that can trigger
391+ // / a task switch, like `async_task_switch` or `swift_asyncLet_get`.
392+ static ThreadPlanSP
393+ CreateRunThroughTaskSwitchingTrampolines (Thread &thread,
394+ StringRef trampoline_name) {
395+ // The signature for `swift_task_switch` is as follows:
396+ // SWIFT_CC(swiftasync)
397+ // void swift_task_switch(
398+ // SWIFT_ASYNC_CONTEXT AsyncContext *resumeContext,
399+ // TaskContinuationFunction *resumeFunction,
400+ // ExecutorRef newExecutor);
401+ //
402+ // The async context given as the first argument is not passed using the
403+ // calling convention's first register, it's passed in the platform's async
404+ // context register. This means the `resumeFunction` parameter uses the
405+ // first ABI register (ex: x86-64: rdi, arm64: x0).
406+ if (trampoline_name == " swift_task_switch" )
407+ return CreateRunThroughTaskSwitchThreadPlan (thread,
408+ LLDB_REGNUM_GENERIC_ARG1);
409+
410+ return nullptr ;
411+ }
412+
400413static lldb::ThreadPlanSP GetStepThroughTrampolinePlan (Thread &thread,
401414 bool stop_others) {
402415 // Here are the trampolines we have at present.
@@ -429,8 +442,9 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
429442 Mangled &mangled_symbol_name = symbol->GetMangled ();
430443 const char *symbol_name = mangled_symbol_name.GetMangledName ().AsCString ();
431444
432- if (mangled_symbol_name.GetDemangledName () == " swift_task_switch" )
433- return CreateRunThroughTaskSwitchThreadPlan (thread);
445+ if (ThreadPlanSP thread_plan = CreateRunThroughTaskSwitchingTrampolines (
446+ thread, mangled_symbol_name.GetDemangledName ()))
447+ return thread_plan;
434448
435449 ThunkKind thunk_kind = GetThunkKind (symbol);
436450 ThunkAction thunk_action = GetThunkAction (thunk_kind);
0 commit comments