Skip to content

[cherry-pick][lldb][swift] Use frame formation as a guide for async unwinding #10687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

felipepiovezan
Copy link

This patch changes how the swift language runtime obtains the async context of the currently executing function.

The old strategy consists of querying unwind plans for what they believe the location of the async register is. This proved problematic in cases where the register is not saved directly, e.g. in arm64e, where the register is signed and moved to a scratch register prior to being saved.

The new strategy relies on ABI guarantees: the async context is always saved at the stack slot immediately beneath where FP is saved. As long as a frame has been formed, we can always access the async context by reading memory @ [CFA-24] (FP is saved in [CFA-16]). Before the frame is formed, the async register can be accessed directly.

In other words, the main problem this patch has to solve is detecting the point at which a frame has been fully formed. This is accomplished by scanning the first few Rows of the assembly unwind plan, until a Row is found where FP's location is "AtCFAPlusOffset". The Row immediately after that is used. This is reliable because async prologues follow this pattern in all tested architectures (x86-64, arm64, arm64e):

// 0. adjust sp
// 1. save lr @ CFA-8
// 2. save fp @ CFA-16
// 3. save async_reg @ CFA-24 << "row immediately after"

For frameless functions, we can always use the async register directly.

While this patch adds no tests, all of the existing stepping tests and tests inspecting variables exercise the new behavior.

(cherry picked from commit d1ac271)

This patch changes how the swift language runtime obtains the async
context of the currently executing function.

The old strategy consists of querying unwind plans for what they believe
the location of the async register is. This proved problematic in cases
where the register is not saved directly, e.g. in arm64e, where the
register is signed and moved to a scratch register prior to being saved.

The new strategy relies on ABI guarantees: the async context is _always_
saved at the stack slot immediately beneath where FP is saved. As long
as a frame has been formed, we can always access the async context by
reading memory @ [CFA-24] (FP is saved in [CFA-16]). Before the frame is
formed, the async register can be accessed directly.

In other words, the main problem this patch has to solve is detecting
the point at which a frame has been fully formed. This is accomplished
by scanning the first few Rows of the assembly unwind plan, until a Row
is found where FP's location is "AtCFAPlusOffset". The Row immediately
after that is used. This is reliable because async prologues follow this
pattern in all tested architectures (x86-64, arm64, arm64e):

// 0. adjust sp
// 1. save lr        @ CFA-8
// 2. save fp        @ CFA-16
// 3. save async_reg @ CFA-24  << "row immediately after"

For frameless functions, we can always use the async register directly.

While this patch adds no tests, all of the existing stepping tests and
tests inspecting variables exercise the new behavior.

(cherry picked from commit d1ac271)
@felipepiovezan felipepiovezan changed the title [lldb][swift] Use frame formation as a guide for async unwinding [cherry-pick][lldb][swift] Use frame formation as a guide for async unwinding May 15, 2025
@felipepiovezan felipepiovezan merged commit 55d4f57 into swiftlang:next May 15, 2025
@felipepiovezan felipepiovezan deleted the felipe/cherry-pick-frame-formation branch May 15, 2025 14:29
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.

1 participant