Skip to content

Don't create a swift async unwind plan when in a function prologue #2645

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

Don't create a swift async unwind plan when in a function prologue

If a swift async function does a standard ABI function call into
a normal function, at the start, we will still have the caller's
async register values (e.g. deref frame pointer shows us an
AsyncContext address with high-nibble flags set).

This patch changes SwiftLanguageRuntime to detect when we are in the
middle of a function prologue, and not return an async unwind plan
in that case.

If a swift async function does a standard ABI function call into
a normal function, at the start, we will still have the caller's
async register values (e.g. deref frame pointer shows us an
AsyncContext address with high-nibble flags set).

This patch changes SwiftLanguageRuntime to detect when we are in the
middle of a function prologue, and not return an async unwind plan
in that case.
@jasonmolenda
Copy link
Author

@swift-ci please test

}
}

if (sc.symbol) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be else if (sc.symbol)? Or is there a reason to test function and symbol?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll piggyback off this question and ask: Does anyone know off hand when this call to CalculateSymbolContext would return only one of function/symbol, but not the other?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Function is based on debug information; Symbol is based on the raw symbol table (here's a list of symbol names and addresses). Symbol may have a prologue description based on the instruction profiler. But the line table based size is going to be the more reliable one. We use the Symbol as a backup if we couldn't find a Function.

@kastiglione
Copy link

Which order should be used: Function; Symbol, or Symbol; Function?

@adrian-prantl mentioned that the line table data for is_prologue_end may not be reliable. WIth Function::GetPrologueByteSize first, as it is now, then is_prologue_end is used in part to determine the end. It may be fine, but if we think that data isn't good enough, then these checks could start with Symbol::GetPrologueByteSize.

@jasonmolenda
Copy link
Author

Which order should be used: Function; Symbol, or Symbol; Function?

Function; Symbol.

@adrian-prantl mentioned that the line table data for is_prologue_end may not be reliable. WIth Function::GetPrologueByteSize first, as it is now, then is_prologue_end is used in part to determine the end. It may be fine, but if we think that data isn't good enough, then these checks could start with Symbol::GetPrologueByteSize.

We already use GetPrologueByteSize for step (determining how far a step should advance into a function before we tell the user we're stopped there) and for breakpoint migration (put a breakpoint on a function name, lldb advances the breakpoint past the prologue). My assumption is that GetPrologueByteSize behaves correctly.

@jasonmolenda
Copy link
Author

@swift-ci please test

@kastiglione
Copy link

kastiglione commented Mar 10, 2021

Thanks for the lesson.

@jasonmolenda jasonmolenda merged commit 0734da1 into swiftlang:swift/main Mar 10, 2021
@jasonmolenda jasonmolenda deleted the no-async-unwind-when-stopped-in-function-prologue branch March 10, 2021 09:58
jasonmolenda added a commit that referenced this pull request Mar 15, 2021
…2645)

* Don't create a swift async unwind plan when in a function prologue

If a swift async function does a standard ABI function call into
a normal function, at the start, we will still have the caller's
async register values (e.g. deref frame pointer shows us an
AsyncContext address with high-nibble flags set).

This patch changes SwiftLanguageRuntime to detect when we are in the
middle of a function prologue, and not return an async unwind plan
in that case.

* If Function found for $pc, don't also look at Symbol

(cherry picked from commit 0734da1)
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