-
Notifications
You must be signed in to change notification settings - Fork 339
[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
[lldb][swift] Create thread plan for stepping through Allocating Init #10576
Conversation
33be91d
to
345eddf
Compare
@swift-ci test |
@swift-ci test macos platform |
1 similar comment
@swift-ci test macos platform |
345eddf
to
7f8c8bc
Compare
@swift-ci test |
7f8c8bc
to
9503b80
Compare
@swift-ci test |
9503b80
to
08b551d
Compare
@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.
08b551d
to
30aa4dc
Compare
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. |
@swift-ci test |
SwiftLanguageRuntime::DemangleSymbolAsNode(symbol_name, ctx); | ||
|
||
using Kind = Node::Kind; | ||
NodePointer class_node = childAtPath( |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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.