Skip to content

[lldb][swift] Implement async funclet comparison based on mangling #9441

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

@felipepiovezan felipepiovezan commented Oct 17, 2024

This PR implements the language plugin changes required to detect whether two funclets belong to the same function. In particular, this fixes an issue where ThreadPlanStepOverRange behaved incorrectly as it believed two virtual frames were different when they were, in fact, the same.

It depends on the upstream change: llvm#112720

Please review each commit on its own

This will enable reuse of this function in a subsequent commit.
CheckGroupOfFuncletsFromDifferentFunctions(nested2_funclets1,
nested2_funclets_top_not_async);
CheckGroupOfFuncletsFromDifferentFunctions(nested2_funclets2,
nested2_funclets_top_not_async);
Copy link
Author

Choose a reason for hiding this comment

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

I know this might seem like a lot of pairwise checks, but this entire test runs in under 5ms on a debug build of the binary.

@felipepiovezan felipepiovezan force-pushed the felipe/swift_compare_async_funclets branch from f2e1217 to 3599daa Compare October 17, 2024 20:16
/// async function.
/// If either SymbolContext is not a funclets, nullopt is returned.
std::optional<bool>
AreEquivalentFunctions(const SymbolContext &sc1,

Choose a reason for hiding this comment

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

The name of this function doesn't describe well what it does.
Also not great: AsyncFuncletsOfSameFunction?

Choose a reason for hiding this comment

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

Where is this used?

Copy link
Author

Choose a reason for hiding this comment

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

The name of this function doesn't describe well what it does.

Also not great: AsyncFuncletsOfSameFunction?

We're renaming it on the upstream PR that introduces the base class interface (see the PR linked previously: llvm#112720)

Copy link
Author

@felipepiovezan felipepiovezan Oct 19, 2024

Choose a reason for hiding this comment

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

Where is this used?

See the upstream PR, it is used by the thread plan

/// If name1 and name2 are both mangled names of async functions, return true
/// iff both correspond to funclets of the same function.
static FuncletComparisonResult
AreFuncletsOfSameAsyncFunction(StringRef name1, StringRef name2);

Choose a reason for hiding this comment

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

Oh, you had the same idea :-)

@felipepiovezan felipepiovezan force-pushed the felipe/swift_compare_async_funclets branch 2 times, most recently from b407672 to 56b8086 Compare October 20, 2024 16:57
This is going to be useful for the Swift Language plugin to identify whether two
symbol contexts are equivalent, an operation which is done by thread plans such
as ThreadPlanStepOverRange.

The implementation compares the following attributes of the mangling tree:

* If these funclets come from a simple async function (as opposed to a closure),
we compare the "Function" child node in the tree.

* If these funclets come from an async closure:
** Their "Number" child node must be the same. This number distinguishes
different closures in the same scope.
** The closure type must be the same.
** If they have a parent closure, it must be identical.
** If they have a parent function, it must be identical.
This checks whether the two provided symbol contexts refer to funclets of the
same async function.

In particular, this fixes an issue in the ThreadPlanStepOverRange algorithm for
async functions.
When the plan stops, it compares the current symbol context to the symbol
context of where it started. An initial comparison is done through StackIDs. If
that comparison says the two are equal, the plan then attempts to confirm the
two SymbolContexts are the same by checking whether the underlying functions are
the same. Because different funclets correspond to different low level
functions, this comparison was failing.
@felipepiovezan felipepiovezan force-pushed the felipe/swift_compare_async_funclets branch from 56b8086 to 063abb3 Compare October 21, 2024 14:24
@felipepiovezan
Copy link
Author

@swift-ci test

@felipepiovezan
Copy link
Author

@swift-ci test platform windows

@felipepiovezan
Copy link
Author

@swift-ci test windows platform

2 similar comments
@felipepiovezan
Copy link
Author

@swift-ci test windows platform

@felipepiovezan
Copy link
Author

@swift-ci test windows platform

@felipepiovezan felipepiovezan merged commit 6c40897 into swiftlang:stable/20240723 Oct 26, 2024
2 of 3 checks passed
@felipepiovezan felipepiovezan deleted the felipe/swift_compare_async_funclets branch October 26, 2024 16:18
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.

2 participants