Skip to content

[lldb] Allow fetching of RA register when above fault handler (#98566) #8976

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

jasonmolenda
Copy link

In RegisterContextUnwind::SavedLocationForRegister we have special logic for retrieving the Return Address register when it has the caller's return address in it. An example would be the lr register on AArch64.

This register is never retrieved from a newer stack frame because it is necessarly overwritten by a normal ABI function call. We allow frame 0 to provide its lr value to get the caller's return address, if it has not been overwritten/saved to stack yet.

When a function is interrupted asynchronously by a POSIX signal (sigtramp), or a fault handler more generally, the sigtramp/fault handler has the entire register context available. In this situation, if the fault handler is frame 0, the function that was async interrupted is frame 1 and frame 2's return address may still be stored in lr. We need to get the lr value for frame 1 from the fault handler in frame 0, to get the return address for frame 2.

Without this fix, a frameless function that faults in a firmware environment (that's where we've seen this issue most commonly) hasn't spilled lr to stack, so we need to retrieve it from the fault handler's full-register-context to find the caller of the frameless function that faulted.

It's an unsurprising fix, all of the work was finding exactly where in RegisterContextUnwind we were only allowing RA register use for frame 0, when it should have been frame 0 or above a fault handler function.

rdar://127518945
(cherry picked from commit fd42417)

…8566)

In RegisterContextUnwind::SavedLocationForRegister we have special logic
for retrieving the Return Address register when it has the caller's
return address in it. An example would be the lr register on AArch64.

This register is never retrieved from a newer stack frame because it is
necessarly overwritten by a normal ABI function call. We allow frame 0
to provide its lr value to get the caller's return address, if it has
not been overwritten/saved to stack yet.

When a function is interrupted asynchronously by a POSIX signal
(sigtramp), or a fault handler more generally, the sigtramp/fault
handler has the entire register context available. In this situation, if
the fault handler is frame 0, the function that was async interrupted is
frame 1 and frame 2's return address may still be stored in lr. We need
to get the lr value for frame 1 from the fault handler in frame 0, to
get the return address for frame 2.

Without this fix, a frameless function that faults in a firmware
environment (that's where we've seen this issue most commonly) hasn't
spilled lr to stack, so we need to retrieve it from the fault handler's
full-register-context to find the caller of the frameless function that
faulted.

It's an unsurprising fix, all of the work was finding exactly where in
RegisterContextUnwind we were only allowing RA register use for frame 0,
when it should have been frame 0 or above a fault handler function.

rdar://127518945
(cherry picked from commit fd42417)
@jasonmolenda
Copy link
Author

@swift-ci test

@jasonmolenda
Copy link
Author

@swift-ci test windows

4 similar comments
@jasonmolenda
Copy link
Author

@swift-ci test windows

@JDevlieghere
Copy link

@swift-ci test windows

@jasonmolenda
Copy link
Author

@swift-ci test windows

@shahmishal
Copy link
Member

@swift-ci test windows

@jasonmolenda jasonmolenda merged commit 188df9b into swiftlang:stable/20230725 Jul 15, 2024
3 checks passed
@jasonmolenda jasonmolenda deleted the cp/r127518945-frameless-function-fault-backtrace-20230725 branch July 15, 2024 22:05
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.

3 participants