Cleaned up the the code that figures out the inlined stack frames given a
symbol context that represents an inlined function. This function has been
renamed internally to:
bool
SymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc,
SymbolContext &next_frame_sc,
Address &next_frame_pc) const;
And externally to:
SBSymbolContext
SBSymbolContext::GetParentOfInlinedScope (const SBAddress &curr_frame_pc,
SBAddress &parent_frame_addr) const;
The correct blocks are now correctly calculated.
Switched the stack backtracing engine (in StackFrameList) and the address
context printing over to using the internal SymbolContext::GetParentOfInlinedScope(...)
so all inlined callstacks will match exactly.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@140910 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBSymbolContext.cpp b/source/API/SBSymbolContext.cpp
index c2b70fb..01118c8 100644
--- a/source/API/SBSymbolContext.cpp
+++ b/source/API/SBSymbolContext.cpp
@@ -266,14 +266,13 @@
}
SBSymbolContext
-SBSymbolContext::GetParentInlinedFrameInfo (const SBAddress &curr_frame_pc,
- bool is_concrete_frame,
- SBAddress &parent_frame_addr) const
+SBSymbolContext::GetParentOfInlinedScope (const SBAddress &curr_frame_pc,
+ SBAddress &parent_frame_addr) const
{
SBSymbolContext sb_sc;
if (m_opaque_ap.get() && curr_frame_pc.IsValid())
{
- if (m_opaque_ap->GetParentInlinedFrameInfo (curr_frame_pc.ref(), is_concrete_frame, sb_sc.ref(), parent_frame_addr.ref()))
+ if (m_opaque_ap->GetParentOfInlinedScope (curr_frame_pc.ref(), sb_sc.ref(), parent_frame_addr.ref()))
return sb_sc;
}
return SBSymbolContext();
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 4ff540d..8933f96 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -1304,12 +1304,13 @@
strm.EOL();
strm.Indent (" Summary: ");
const uint32_t save_indent = strm.GetIndentLevel ();
- strm.SetIndentLevel (save_indent + 11);
+ strm.SetIndentLevel (save_indent + 13);
so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
strm.SetIndentLevel (save_indent);
// Print out detailed address information when verbose is enabled
if (verbose)
{
+ strm.EOL();
so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
}
strm.IndentLess();
diff --git a/source/Core/Broadcaster.cpp b/source/Core/Broadcaster.cpp
index fe1b716..1d264a6 100644
--- a/source/Core/Broadcaster.cpp
+++ b/source/Core/Broadcaster.cpp
@@ -40,22 +40,24 @@
if (log)
log->Printf ("%p Broadcaster::~Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString());
- // Scope for "listeners_locker"
- {
- Mutex::Locker listeners_locker(m_listeners_mutex);
-
- // Make sure the listener forgets about this broadcaster. We do
- // this in the broadcaster in case the broadcaster object initiates
- // the removal.
-
- collection::iterator pos, end = m_listeners.end();
- for (pos = m_listeners.begin(); pos != end; ++pos)
- pos->first->BroadcasterWillDestruct (this);
-
- m_listeners.clear();
- }
+ Clear();
}
+void
+Broadcaster::Clear()
+{
+ Mutex::Locker listeners_locker(m_listeners_mutex);
+
+ // Make sure the listener forgets about this broadcaster. We do
+ // this in the broadcaster in case the broadcaster object initiates
+ // the removal.
+
+ collection::iterator pos, end = m_listeners.end();
+ for (pos = m_listeners.begin(); pos != end; ++pos)
+ pos->first->BroadcasterWillDestruct (this);
+
+ m_listeners.clear();
+}
const ConstString &
Broadcaster::GetBroadcasterName ()
{
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index 83c226b..583c1ca 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -249,6 +249,7 @@
Debugger::Clear()
{
CleanUpInputReaders();
+ m_listener.Clear();
int num_targets = m_target_list.GetNumTargets();
for (int i = 0; i < num_targets; i++)
{
diff --git a/source/Core/Listener.cpp b/source/Core/Listener.cpp
index b1da364..7b0888a 100644
--- a/source/Core/Listener.cpp
+++ b/source/Core/Listener.cpp
@@ -55,6 +55,8 @@
m_broadcasters.clear();
m_cond_wait.SetValue (false, eBroadcastNever);
m_broadcasters.clear();
+ Mutex::Locker event_locker(m_events_mutex);
+ m_events.clear();
}
uint32_t
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 3d26383..d39fbe4 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -152,6 +152,11 @@
}
// m_mach_process.UnregisterNotificationCallbacks (this);
Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
}
//----------------------------------------------------------------------
diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp
index d0f8ff3..2b00cf8 100644
--- a/source/Symbol/Block.cpp
+++ b/source/Symbol/Block.cpp
@@ -186,95 +186,6 @@
}
void
-Block::DumpStopContext
-(
- Stream *s,
- const SymbolContext *sc_ptr,
- const Declaration *child_inline_call_site,
- bool show_fullpaths,
- bool show_inline_blocks)
-{
- const InlineFunctionInfo* inline_info = NULL;
- Block* inlined_block;
- if (sc_ptr)
- inlined_block = GetContainingInlinedBlock ();
- else
- inlined_block = GetInlinedParent();
-
- if (inlined_block)
- inline_info = inlined_block->GetInlinedFunctionInfo();
- const Declaration *inline_call_site = child_inline_call_site;
- if (inline_info)
- {
- inline_call_site = &inline_info->GetCallSite();
- if (sc_ptr)
- {
- // First frame in a frame with inlined functions
- s->PutCString (" [inlined]");
- }
- if (show_inline_blocks && child_inline_call_site)
- s->EOL();
- else
- s->PutChar(' ');
-
- if (sc_ptr == NULL)
- s->Indent();
-
- s->PutCString(inline_info->GetName ().AsCString());
-
- if (child_inline_call_site && child_inline_call_site->IsValid())
- {
- s->PutCString(" at ");
- child_inline_call_site->DumpStopContext (s, show_fullpaths);
- }
- }
-
- // The first call to this function from something that has a symbol
- // context will pass in a valid sc_ptr. Subsequent calls to this function
- // from this function for inline purposes will NULL out sc_ptr. So on the
- // first time through we dump the line table entry (which is always at the
- // deepest inline code block). And subsequent calls to this function we
- // will use hte inline call site information to print line numbers.
- if (sc_ptr)
- {
- // If we have any inlined functions, this will be the deepest most
- // inlined location
- if (sc_ptr->line_entry.IsValid())
- {
- s->PutCString(" at ");
- sc_ptr->line_entry.DumpStopContext (s, show_fullpaths);
- }
- }
-
- if (show_inline_blocks)
- {
- if (inlined_block)
- {
- inlined_block->Block::DumpStopContext (s,
- NULL,
- inline_call_site,
- show_fullpaths,
- show_inline_blocks);
- }
- else if (child_inline_call_site)
- {
- Function *function = CalculateSymbolContextFunction();
- if (function)
- {
- s->EOL();
- s->Indent (function->GetMangled().GetName().AsCString());
- if (child_inline_call_site && child_inline_call_site->IsValid())
- {
- s->PutCString(" at ");
- child_inline_call_site->DumpStopContext (s, show_fullpaths);
- }
- }
- }
- }
-}
-
-
-void
Block::DumpSymbolContext(Stream *s)
{
Function *function = CalculateSymbolContextFunction();
diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp
index 3bc4565..85da979 100644
--- a/source/Symbol/SymbolContext.cpp
+++ b/source/Symbol/SymbolContext.cpp
@@ -138,12 +138,14 @@
if (function != NULL)
{
+ SymbolContext inline_parent_sc;
+ Address inline_parent_addr;
if (function->GetMangled().GetName())
{
dumped_something = true;
function->GetMangled().GetName().Dump(s);
}
-
+
if (addr.IsValid())
{
const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
@@ -154,12 +156,34 @@
}
}
- if (block != NULL)
+ if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr))
{
- s->IndentMore();
- block->DumpStopContext (s, this, NULL, show_fullpaths, show_inlined_frames);
- s->IndentLess();
dumped_something = true;
+ Block *inlined_block = block->GetContainingInlinedBlock();
+ const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo();
+ s->Printf (" [inlined] %s", inlined_block_info->GetName().GetCString());
+
+ lldb_private::AddressRange block_range;
+ if (inlined_block->GetRangeContainingAddress(addr, block_range))
+ {
+ const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
+ if (inlined_function_offset)
+ {
+ s->Printf(" + %llu", inlined_function_offset);
+ }
+ }
+ const Declaration &call_site = inlined_block_info->GetCallSite();
+ if (call_site.IsValid())
+ {
+ s->PutCString(" at ");
+ call_site.DumpStopContext (s, show_fullpaths);
+ }
+ if (show_inlined_frames)
+ {
+ s->EOL();
+ s->Indent();
+ return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames);
+ }
}
else
{
@@ -488,87 +512,46 @@
}
bool
-SymbolContext::GetParentInlinedFrameInfo (const Address &curr_frame_pc,
- bool is_concrete_frame,
- SymbolContext &next_frame_sc,
- Address &inlined_frame_addr) const
+SymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc,
+ SymbolContext &next_frame_sc,
+ Address &next_frame_pc) const
{
next_frame_sc.Clear();
- inlined_frame_addr.Clear();
+ next_frame_pc.Clear();
if (block)
{
- bool concrete_has_inlines = false;
- Block *curr_inlined_block = NULL;
- Block *next_inlined_block = NULL;
//const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
- if (is_concrete_frame)
+
+ // In order to get the parent of an inlined function we first need to
+ // see if we are in an inlined block as "this->block" could be an
+ // inlined block, or a parent of "block" could be. So lets check if
+ // this block or one of this blocks parents is an inlined function.
+ Block *curr_inlined_block = block->GetContainingInlinedBlock();
+ if (curr_inlined_block)
{
- curr_inlined_block = block->GetContainingInlinedBlock();
- if (curr_inlined_block)
- {
- concrete_has_inlines = true;
- next_inlined_block = curr_inlined_block->GetInlinedParent();
- }
- }
- else
- {
- curr_inlined_block = block;
- next_inlined_block = block->GetInlinedParent();
- }
-
- if (next_inlined_block)
- {
- next_inlined_block->CalculateSymbolContext (&next_frame_sc);
-
+ // "this->block" is contained in an inline function block, so to
+ // get the scope above the inlined block, we get the parent of the
+ // inlined block itself
+ Block *next_frame_block = curr_inlined_block->GetParent();
+ // Now calculate the symbol context of the containing block
+ next_frame_block->CalculateSymbolContext (&next_frame_sc);
+
+ // If we get here we weren't able to find the return line entry using the nesting of the blocks and
+ // the line table. So just use the call site info from our inlined block.
+
AddressRange range;
bool got_range = curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range);
assert (got_range);
- const InlineFunctionInfo* inline_info = next_inlined_block->GetInlinedFunctionInfo();
- if (inline_info)
- {
- inlined_frame_addr = range.GetBaseAddress();
- next_frame_sc.line_entry.range.GetBaseAddress() = inlined_frame_addr;
- next_frame_sc.line_entry.file = inline_info->GetCallSite().GetFile();
- next_frame_sc.line_entry.line = inline_info->GetCallSite().GetLine();
- next_frame_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
- return true;
- }
- }
- else if (is_concrete_frame && !concrete_has_inlines)
- {
- // This is the symbol context for the frame that was found using the
- // PC value and there are no inlined blocks so there are no inlined
- // parent frames.
- return false;
- }
- else
- {
- // We have had inlined frames before and now we are at the function
- // instance that called the inlined frames.
- // The SymbolContext object should contain a previous inline symbol
- // context which we need to use to get the file, line and column info
- const InlineFunctionInfo* inline_info = curr_inlined_block->GetInlinedFunctionInfo();
- if (inline_info)
- {
- Block *parent_block = curr_inlined_block->GetParent();
- if (parent_block)
- {
- parent_block->CalculateSymbolContext (&next_frame_sc);
-
- AddressRange range;
- if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range))
- {
- inlined_frame_addr = range.GetBaseAddress();
- //const addr_t range_file_file_addr = inlined_frame_addr.GetFileAddress();
- next_frame_sc.line_entry.range.GetBaseAddress() = inlined_frame_addr;
- next_frame_sc.line_entry.file = inline_info->GetCallSite().GetFile();
- next_frame_sc.line_entry.line = inline_info->GetCallSite().GetLine();
- next_frame_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
- return true;
- }
- }
- }
+ // To see there this new frame block it, we need to look at the
+ // call site information from
+ const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo();
+ next_frame_pc = range.GetBaseAddress();
+ next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
+ next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
+ next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine();
+ next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn();
+ return true;
}
}
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index 384f9e8..15fa5d0 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -644,6 +644,9 @@
void
Process::Finalize()
{
+ // Clear our broadcaster before we proceed with destroying
+ Broadcaster::Clear();
+
// Do any cleanup needed prior to being destructed... Subclasses
// that override this method should call this superclass method as well.
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp
index 3f74781..3d83423 100644
--- a/source/Target/StackFrameList.cpp
+++ b/source/Target/StackFrameList.cpp
@@ -112,64 +112,28 @@
m_frames.push_back (unwind_frame_sp);
}
- Block *unwind_block = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock).block;
-
+ SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock | eSymbolContextFunction);
+ Block *unwind_block = unwind_sc.block;
if (unwind_block)
{
- Block *inlined_block = unwind_block->GetContainingInlinedBlock();
- if (inlined_block)
+ Address curr_frame_address = unwind_frame_sp->GetFrameCodeAddress();
+ SymbolContext next_frame_sc;
+ Address next_frame_address;
+
+ while (unwind_sc.GetParentOfInlinedScope(curr_frame_address, next_frame_sc, next_frame_address))
{
- for (; inlined_block != NULL; inlined_block = inlined_block->GetInlinedParent ())
- {
- SymbolContext inline_sc;
- Block *parent_block = inlined_block->GetInlinedParent();
-
- const bool is_inlined_frame = parent_block != NULL;
-
- if (parent_block == NULL)
- parent_block = inlined_block->GetParent();
-
- parent_block->CalculateSymbolContext (&inline_sc);
-
- Address previous_frame_lookup_addr (m_frames.back()->GetFrameCodeAddress());
- if (unwind_frame_sp->GetFrameIndex() > 0 && m_frames.back().get() == unwind_frame_sp.get())
- previous_frame_lookup_addr.Slide (-1);
-
- AddressRange range;
- inlined_block->GetRangeContainingAddress (previous_frame_lookup_addr, range);
-
- const InlineFunctionInfo* inline_info = inlined_block->GetInlinedFunctionInfo();
- assert (inline_info);
- inline_sc.line_entry.range.GetBaseAddress() = m_frames.back()->GetFrameCodeAddress();
- inline_sc.line_entry.file = inline_info->GetCallSite().GetFile();
- inline_sc.line_entry.line = inline_info->GetCallSite().GetLine();
- inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
-
StackFrameSP frame_sp(new StackFrame (m_frames.size(),
idx,
m_thread,
unwind_frame_sp->GetRegisterContextSP (),
cfa,
- range.GetBaseAddress(),
- &inline_sc)); // The symbol context for this inline frame
-
- if (is_inlined_frame)
- {
- // Use the block with the inlined function info
- // as the symbol context since we want this frame
- // to have only the variables for the inlined function
- frame_sp->SetSymbolContextScope (parent_block);
- }
- else
- {
- // This block is not inlined with means it has no
- // inlined parents either, so we want to use the top
- // most function block.
- frame_sp->SetSymbolContextScope (&unwind_frame_sp->GetSymbolContext (eSymbolContextFunction).function->GetBlock(false));
- }
-
+ next_frame_address,
+ &next_frame_sc));
+
m_frames.push_back (frame_sp);
- }
+ unwind_sc = next_frame_sc;
+ curr_frame_address = next_frame_address;
+
}
}
}