-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Add the ability to break on call-site locations, improve inline stepping #112939
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
Changes from all commits
9c6705b
7a60871
a19b3dc
b35e42b
ecda9b3
8662acf
38f883f
03764f2
594fb63
e3c26b0
9861c7d
a2aeab6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -508,8 +508,20 @@ void BreakpointLocation::GetDescription(Stream *s, | |
s->PutCString("re-exported target = "); | ||
else | ||
s->PutCString("where = "); | ||
|
||
// If there's a preferred line entry for printing, use that. | ||
bool show_function_info = true; | ||
if (auto preferred = GetPreferredLineEntry()) { | ||
sc.line_entry = *preferred; | ||
// FIXME: We're going to get the function name wrong when the preferred | ||
// line entry is not the lowest one. For now, just leave the function | ||
// out in this case, but we really should also figure out how to easily | ||
// fake the function name here. | ||
show_function_info = false; | ||
} | ||
sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address, | ||
false, true, false, true, true, true); | ||
false, true, false, show_function_info, | ||
show_function_info, show_function_info); | ||
} else { | ||
if (sc.module_sp) { | ||
s->EOL(); | ||
|
@@ -537,7 +549,10 @@ void BreakpointLocation::GetDescription(Stream *s, | |
if (sc.line_entry.line > 0) { | ||
s->EOL(); | ||
s->Indent("location = "); | ||
sc.line_entry.DumpStopContext(s, true); | ||
if (auto preferred = GetPreferredLineEntry()) | ||
preferred->DumpStopContext(s, true); | ||
else | ||
sc.line_entry.DumpStopContext(s, true); | ||
} | ||
|
||
} else { | ||
|
@@ -656,6 +671,50 @@ void BreakpointLocation::SendBreakpointLocationChangedEvent( | |
} | ||
} | ||
|
||
std::optional<uint32_t> BreakpointLocation::GetSuggestedStackFrameIndex() { | ||
auto preferred_opt = GetPreferredLineEntry(); | ||
if (!preferred_opt) | ||
return {}; | ||
LineEntry preferred = *preferred_opt; | ||
SymbolContext sc; | ||
if (!m_address.CalculateSymbolContext(&sc)) | ||
return {}; | ||
// Don't return anything special if frame 0 is the preferred line entry. | ||
// We not really telling the stack frame list to do anything special in that | ||
// case. | ||
if (!LineEntry::Compare(sc.line_entry, preferred)) | ||
return {}; | ||
|
||
if (!sc.block) | ||
return {}; | ||
|
||
// Blocks have their line info in Declaration form, so make one here: | ||
Declaration preferred_decl(preferred.GetFile(), preferred.line, | ||
preferred.column); | ||
|
||
uint32_t depth = 0; | ||
Block *inlined_block = sc.block->GetContainingInlinedBlock(); | ||
while (inlined_block) { | ||
// If we've moved to a block that this isn't the start of, that's not | ||
// our inlining info or call site, so we can stop here. | ||
Address start_address; | ||
if (!inlined_block->GetStartAddress(start_address) || | ||
start_address != m_address) | ||
return {}; | ||
|
||
const InlineFunctionInfo *info = inlined_block->GetInlinedFunctionInfo(); | ||
if (info) { | ||
if (preferred_decl == info->GetDeclaration()) | ||
return depth; | ||
if (preferred_decl == info->GetCallSite()) | ||
return depth + 1; | ||
} | ||
inlined_block = inlined_block->GetInlinedParent(); | ||
depth++; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should there be a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would mean there were cycles in the blocks? I don't think we guard against that anywhere else that we're traversing the block structure. |
||
} | ||
return {}; | ||
} | ||
|
||
void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) { | ||
m_address = swap_from->m_address; | ||
m_should_resolve_indirect_functions = | ||
|
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.
Would a solution that changed
GetPreferredLineEntry()
to beGetPreferredSymbolContext()
where it would return aSymbolContext
object where anything that is valid in theSymbolContext
would end up overriding the actual symbol context insc
? We might want to add a new function like:That would calll
m_address.CalculateSymbolContext(&sc);
and then insert any preferred entries into that symbol context. That would allow anyone to get the right symbol context for aBreakpointLocation
easily. Then this function would change or need to know anything about the preferred stuff.Uh oh!
There was an error while loading. Please reload this page.
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.
What would it mean to replace the Module, the CompileUnit or the Function? This is for a breakpoint location, so whatever we do has to result in this being the same address. I was hesitant to introduce a more general "breakpoint gets to modify its symbol context" if I didn't know what it meant or how to ensure we didn't end up with a SymbolContext that wasn't at the breakpoint location's address. I was originally planning to JUST store the "inlined call stack depth" to make it clear this couldn't change the PC value, but that ended up being more annoying than helpful.
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.
I added one more change here, since the intention is that you cannot change the PC of the breakpoint Location by setting a PreferredLineEntry, I changed the code to actually check that when you call SetPreferredLineEntry. I put in an assert in the setter, so we can catch any violations of this in the testsuite, and then if this happens IRL, I made the BreakpointLocation log the event and ignore the setting.