Skip to content

[lldb] If the function cannot be found, use the symbol to get instructions. #7114

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

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,25 @@ def test(self):
target, _, thread, _ = lldbutil.run_to_source_breakpoint(self, "await f()", src)
self.assertEqual(thread.frame[0].function.mangled, "$s1a5entryO4mainyyYaFZ")

function = target.FindFunctions("$s1a5entryO4mainyyYaFZTQ0_")[0].function
instructions = list(function.GetInstructions(target))
sym_ctx_list = target.FindFunctions("$s1a5entryO4mainyyYaFZTQ0_", lldb.eFunctionNameTypeAuto)

Choose a reason for hiding this comment

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

eFunctionNameTypeAuto is effectively the default parameter value, so it seems it can be left off.

self.assertEquals(sym_ctx_list.GetSize(), 1)
symbolContext = sym_ctx_list.GetContextAtIndex(0)

Choose a reason for hiding this comment

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

for consistency, could you name this symbol_context or symbol_ctx, thanks.

Copy link
Author

Choose a reason for hiding this comment

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

Sorry, my mistake.
I will update if this PR is still needed.

function = symbolContext.GetFunction()
if function:
instructions = list(function.GetInstructions(target))
else:
symbol = symbolContext.GetSymbol()
self.assertIsNotNone(symbol)
instructions = list(symbol.GetInstructions(target))
Comment on lines +24 to +27

Choose a reason for hiding this comment

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

this seems like the crux of the change, is that correct? Does this mean the test is being run without debug info? Or does it mean that even with debug info, somehow GetFunction returns None? If the reason for this else case is understood, then could you add a comment explaining?

Copy link
Author

Choose a reason for hiding this comment

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

Yes.

Copy link
Author

Choose a reason for hiding this comment

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

I may know what the problem is. If I understand correctly, GetFunction is taken from the debuginfo.
An incorrect DW_TAG_subprogram caused the GetFunction returns None.


# Expected to be a trampoline that tail calls `swift_task_switch`.
self.assertIn("swift_task_switch", instructions[-1].GetComment(target))
for inst in reversed(instructions):
control_flow_kind = inst.GetControlFlowKind(target)
if control_flow_kind == lldb.eInstructionControlFlowKindOther:
continue
Comment on lines +31 to +33

Choose a reason for hiding this comment

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

can you say why some instructions need to be skipped? Padding instructions?

Copy link
Author

Choose a reason for hiding this comment

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

Yes. Getting from the symbol will include the padding directive at the end.
But I'm not clear on lldb's difference between GetSymbol and GetFunction.

self.assertEqual(control_flow_kind, lldb.eInstructionControlFlowKindJump)
self.assertIn("swift_task_switch", inst.GetComment(target))
break

# Using the line table, build a set of the non-zero line numbers for
# this this function - and verify that there is exactly one line.
Expand Down