@@ -361,23 +361,13 @@ class ThreadPlanRunToAddressOnAsyncCtx : public ThreadPlan {
361
361
362
362
// / Given a thread that is stopped at the start of swift_task_switch, create a
363
363
// / 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) {
376
367
RegisterContextSP reg_ctx =
377
368
thread.GetStackFrameAtIndex (0 )->GetRegisterContext ();
378
- constexpr unsigned resume_fn_regnum = LLDB_REGNUM_GENERIC_ARG1;
379
369
unsigned resume_fn_reg = reg_ctx->ConvertRegisterKindToRegisterNumber (
380
- RegisterKind::eRegisterKindGeneric, resume_fn_regnum );
370
+ RegisterKind::eRegisterKindGeneric, resume_fn_generic_regnum );
381
371
uint64_t resume_fn_ptr = reg_ctx->ReadRegisterAsUnsigned (resume_fn_reg, 0 );
382
372
if (!resume_fn_ptr)
383
373
return {};
@@ -397,6 +387,41 @@ static ThreadPlanSP CreateRunThroughTaskSwitchThreadPlan(Thread &thread) {
397
387
thread, resume_fn_ptr, async_ctx);
398
388
}
399
389
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
+ // The signature for `swift_asyncLet_get` and `swift_asyncLet_finish` are the
410
+ // same. Like `task_switch`, the async context (first argument) uses the async
411
+ // context register, and not the arg1 register; as such, the continuation
412
+ // funclet can be found in arg3.
413
+ //
414
+ // swift_asyncLet_get(SWIFT_ASYNC_CONTEXT AsyncContext *,
415
+ // AsyncLet *,
416
+ // void *,
417
+ // TaskContinuationFunction *,
418
+ if (trampoline_name == " swift_asyncLet_get" ||
419
+ trampoline_name == " swift_asyncLet_finish" )
420
+ return CreateRunThroughTaskSwitchThreadPlan (thread,
421
+ LLDB_REGNUM_GENERIC_ARG3);
422
+ return nullptr ;
423
+ }
424
+
400
425
static lldb::ThreadPlanSP GetStepThroughTrampolinePlan (Thread &thread,
401
426
bool stop_others) {
402
427
// Here are the trampolines we have at present.
@@ -429,8 +454,9 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
429
454
Mangled &mangled_symbol_name = symbol->GetMangled ();
430
455
const char *symbol_name = mangled_symbol_name.GetMangledName ().AsCString ();
431
456
432
- if (mangled_symbol_name.GetDemangledName () == " swift_task_switch" )
433
- return CreateRunThroughTaskSwitchThreadPlan (thread);
457
+ if (ThreadPlanSP thread_plan = CreateRunThroughTaskSwitchingTrampolines (
458
+ thread, mangled_symbol_name.GetDemangledName ()))
459
+ return thread_plan;
434
460
435
461
ThunkKind thunk_kind = GetThunkKind (symbol);
436
462
ThunkAction thunk_action = GetThunkAction (thunk_kind);
0 commit comments