Skip to content

[lldb][swift] Create thread plan for stepping through Allocating Init #10576

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 Apr 29, 2025

These trampolines have a well defined target, which can be extracted
from the demangle tree. A similar strategy is already adopted for
stepping into conformance code. This allows LLDB to create a
RunToAddress plan with a target address, which is obtained by searching
the Module for functions matching <class_name>.Init.

We already had a test for this, but we rely on the "step avoid
libraries" setting to emulate the case of "avoid libraries without debug
info". However, they are not exactly equivalent, so the test mislead us
into believing stepping was working. A future patch should try to fold
the setting-checking code into
ThreadPlanShouldStopHere::DefaultShouldStopCallback.

With this patch, the test now works regardless of whether debug info is
present or not.

To make this work, this commit also teaches the Swift language runtime
how to recognize "type metadata accessors". These are thunks in the
sense that they jump to some other code, but not user code. Their
purposes is to eventually send the "self" message to the SwiftObject the
first time they run. As such, they should just be stepped out from,
which is accomplished by having the runtime recognize them as
trampolines but not provide any specific actions, relying on the default
behavior of ShouldStopHere.

Prior to this change, this would sometimes work accidentally because all
the functions involved had line 0 debug information, and the debugger
would keep stepping through all of them. However, in debug builds of
x86, this strategy failed; sometimes the computed Symbol size is larger
than the line entry for these functions, and so the detection "all line
0" fails. Relying on this is error-prone and slow, as it causes the
debugger to stop many times.

@felipepiovezan felipepiovezan requested a review from a team as a code owner April 29, 2025 02:04
@felipepiovezan felipepiovezan force-pushed the felipe/fix-stepping-into-allocating-init branch from 33be91d to 345eddf Compare April 29, 2025 02:04
@felipepiovezan
Copy link
Author

@swift-ci test

@felipepiovezan
Copy link
Author

@swift-ci test macos platform

1 similar comment
@felipepiovezan
Copy link
Author

@swift-ci test macos platform

@felipepiovezan felipepiovezan force-pushed the felipe/fix-stepping-into-allocating-init branch from 345eddf to 7f8c8bc Compare May 9, 2025 19:29
@felipepiovezan
Copy link
Author

@swift-ci test

@felipepiovezan felipepiovezan force-pushed the felipe/fix-stepping-into-allocating-init branch from 7f8c8bc to 9503b80 Compare May 9, 2025 19:31
@felipepiovezan
Copy link
Author

@swift-ci test

@felipepiovezan felipepiovezan force-pushed the felipe/fix-stepping-into-allocating-init branch from 9503b80 to 08b551d Compare May 12, 2025 22:19
@felipepiovezan felipepiovezan requested a review from jimingham May 12, 2025 22:19
@felipepiovezan
Copy link
Author

@swift-ci test

These trampolines have a well defined target, which can be extracted
from the demangle tree. A similar strategy is already adopted for
stepping into conformance code. This allows LLDB to create a
RunToAddress plan with a target address, which is obtained by searching
the Module for functions matching `<class_name>.Init`.

We already had a test for this, but we rely on the "step avoid
libraries" setting to emulate the case of "avoid libraries without debug
info". However, they are not exactly equivalent, so the test mislead us
into believing stepping was working. A future patch should try to fold
the setting-checking code into
ThreadPlanShouldStopHere::DefaultShouldStopCallback.

With this patch, the test now works regardless of whether debug info is
present or not.

To make this work, this commit also teaches the Swift language runtime
how to recognize "type metadata accessors". These are thunks in the
sense that they jump to some other code, but not user code. Their
purposes is to eventually send the "self" message to the SwiftObject the
first time they run. As such, they should just be stepped out from,
which is accomplished by having the runtime recognize them as
trampolines but not provide any specific actions, relying on the default
behavior of ShouldStopHere.

Prior to this change, this would sometimes work accidentally because all
the functions involved had line 0 debug information, and the debugger
would keep stepping through _all_ of them. However, in debug builds of
x86, this strategy failed; sometimes the computed Symbol size is larger
than the line entry for these functions, and so the detection "all line
0" fails. Relying on this is error-prone and slow, as it causes the
debugger to stop many times.
@felipepiovezan felipepiovezan force-pushed the felipe/fix-stepping-into-allocating-init branch from 08b551d to 30aa4dc Compare May 12, 2025 22:21
@felipepiovezan
Copy link
Author

After discussing this with Jim, I changed the implementation to use a much more targeted plan: run-to-address instead of stepping-in-to-target.

@felipepiovezan
Copy link
Author

@swift-ci test

SwiftLanguageRuntime::DemangleSymbolAsNode(symbol_name, ctx);

using Kind = Node::Kind;
NodePointer class_node = childAtPath(

Choose a reason for hiding this comment

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

Do you need to check that demangled_node is non-null before calling childAtPath?

Copy link
Author

Choose a reason for hiding this comment

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

Oh, the function childAtPath is safe, it checks for nullptr. (If it didn't, we would have changed it to take a reference instead)

Choose a reason for hiding this comment

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

Okay.

Copy link

@jimingham jimingham left a comment

Choose a reason for hiding this comment

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

LGTM

@adrian-prantl adrian-prantl merged commit d1d3d29 into swiftlang:swift/release/6.2 May 13, 2025
3 checks passed
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