[Lldb-commits] [lldb] r123045 - in /lldb/trunk: include/lldb/Core/Address.h include/lldb/Symbol/FuncUnwinders.h include/lldb/Symbol/UnwindTable.h source/Core/Address.cpp source/Symbol/FuncUnwinders.cpp source/Symbol/UnwindTable.cpp
Greg Clayton
gclayton at apple.com
Fri Jan 7 16:05:13 PST 2011
Author: gclayton
Date: Fri Jan 7 18:05:12 2011
New Revision: 123045
URL: http://llvm.org/viewvc/llvm-project?rev=123045&view=rev
Log:
Fixed issues with the unwinding code where the collection of FuncUnwinders
was being searched and sorted using a shared pointer as the value which means
the pointer value was what was being searched for. This means that anytime
you did a stack backtrace, the collection of FuncUnwinders doubled and then
the array or shared pointer got sorted (by pointer value), so you had an ever
increasing collection of shared pointer where a match was never found. This
means we had a ton of duplicates in this table and would cause issues after
one had been debugging for a long time.
Modified:
lldb/trunk/include/lldb/Core/Address.h
lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
lldb/trunk/include/lldb/Symbol/UnwindTable.h
lldb/trunk/source/Core/Address.cpp
lldb/trunk/source/Symbol/FuncUnwinders.cpp
lldb/trunk/source/Symbol/UnwindTable.cpp
Modified: lldb/trunk/include/lldb/Core/Address.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Address.h?rev=123045&r1=123044&r2=123045&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Address.h (original)
+++ lldb/trunk/include/lldb/Core/Address.h Fri Jan 7 18:05:12 2011
@@ -434,15 +434,29 @@
lldb::addr_t m_offset; ///< Offset into section if \a m_section != NULL, else the absolute address value.
};
-//bool operator< (const Address& lhs, const Address& rhs);
-//bool operator<= (const Address& lhs, const Address& rhs);
-//bool operator> (const Address& lhs, const Address& rhs);
-//bool operator>= (const Address& lhs, const Address& rhs);
+
+//----------------------------------------------------------------------
+// NOTE: Be careful using this operator. It can correctly compare two
+// addresses from the same Module correctly. It can't compare two
+// addresses from different modules in any meaningful way, but it will
+// compare the module pointers.
+//
+// To sum things up:
+// - works great for addresses within the same module
+// - it works for addresses across multiple modules, but don't expect the
+// address results to make much sense
+//
+// This basically lets Address objects be used in ordered collection
+// classes.
+//----------------------------------------------------------------------
+bool operator< (const Address& lhs, const Address& rhs);
+bool operator> (const Address& lhs, const Address& rhs);
+
+
+
bool operator== (const Address& lhs, const Address& rhs);
bool operator!= (const Address& lhs, const Address& rhs);
-//Stream& operator << (Stream& strm, const Address& so_addr);
-
} // namespace lldb_private
#endif // liblldb_Address_h_
Modified: lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/FuncUnwinders.h?rev=123045&r1=123044&r2=123045&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/FuncUnwinders.h (original)
+++ lldb/trunk/include/lldb/Symbol/FuncUnwinders.h Fri Jan 7 18:05:12 2011
@@ -72,26 +72,22 @@
UnwindAssemblyProfiler *m_assembly_profiler;
AddressRange m_range;
- UnwindPlan* m_unwind_at_call_site;
- UnwindPlan* m_unwind_at_non_call_site;
- UnwindPlan* m_fast_unwind;
- UnwindPlan* m_arch_default_unwind;
-
+ std::auto_ptr<UnwindPlan> m_unwind_at_call_site_ap;
+ std::auto_ptr<UnwindPlan> m_unwind_at_non_call_site_ap;
+ std::auto_ptr<UnwindPlan> m_fast_unwind_ap;
+ UnwindPlan *m_arch_default_unwind;
+
+ bool m_tried_unwind_at_call_site:1,
+ m_tried_unwind_at_non_call_site:1,
+ m_tried_fast_unwind:1,
+ m_tried_arch_default_unwind:1;
+
Address m_first_non_prologue_insn;
DISALLOW_COPY_AND_ASSIGN (FuncUnwinders);
}; // class FuncUnwinders
-inline bool
-operator<(const FuncUnwinders& a, const FuncUnwinders& b)
-{
- if (a.GetFunctionStartAddress().GetOffset() < b.GetFunctionStartAddress().GetOffset())
- return true;
- else
- return false;
-}
-
} // namespace lldb_private
Modified: lldb/trunk/include/lldb/Symbol/UnwindTable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/UnwindTable.h?rev=123045&r1=123044&r2=123045&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/UnwindTable.h (original)
+++ lldb/trunk/include/lldb/Symbol/UnwindTable.h Fri Jan 7 18:05:12 2011
@@ -11,7 +11,7 @@
#ifndef liblldb_UnwindTable_h
#define liblldb_UnwindTable_h
-#include <vector>
+#include <map>
#include "lldb/lldb-private.h"
@@ -34,11 +34,14 @@
GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc);
private:
- void initialize ();
-
- typedef std::vector<lldb::FuncUnwindersSP> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
+ void
+ Dump (Stream &s);
+
+ void Initialize ();
+
+ typedef std::map<lldb::addr_t, lldb::FuncUnwindersSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
ObjectFile& m_object_file;
collection m_unwinds;
Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=123045&r1=123044&r2=123045&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Fri Jan 7 18:05:12 2011
@@ -18,46 +18,6 @@
using namespace lldb;
using namespace lldb_private;
-//static size_t
-//ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
-//{
-// if (exe_scope == NULL)
-// return 0;
-//
-// lldb::AddressType addr_type = eAddressTypeInvalid;
-// addr_t addr = LLDB_INVALID_ADDRESS;
-//
-// Process *process = exe_scope->CalculateProcess();
-//
-// if (process && process->IsAlive())
-// {
-// addr = address.GetLoadAddress(process);
-// if (addr != LLDB_INVALID_ADDRESS)
-// addr_type = eAddressTypeLoad;
-// }
-//
-// if (addr == LLDB_INVALID_ADDRESS)
-// {
-// addr = address.GetFileAddress();
-// if (addr != LLDB_INVALID_ADDRESS)
-// addr_type = eAddressTypeFile;
-// }
-//
-// if (addr_type == eAddressTypeInvalid)
-// return false;
-//
-// Target *target = exe_scope->CalculateTarget();
-// if (target)
-// {
-// Error error;
-// ObjectFile *objfile = NULL;
-// if (address.GetModule())
-// objfile = address.GetModule()->GetObjectFile();
-// return target->ReadMemory (addr_type, addr, dst, dst_len, error, objfile);
-// }
-// return 0;
-//}
-
static size_t
ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
{
@@ -282,25 +242,6 @@
return false; // Failed to resolve this address to a section offset value
}
-//bool
-//Address::ResolveAddressUsingLoadSections (addr_t addr, const SectionList *sections)
-//{
-// if (sections)
-// m_section = sections->FindSectionContainingLoadAddress(addr).get();
-// else
-// m_section = NULL;
-//
-// if (m_section != NULL)
-// {
-// assert( m_section->ContainsLoadAddress(addr) );
-// m_offset = addr - m_section->GetLoadBaseAddress();
-// return true; // Successfully transformed addr into a section offset address
-// }
-//
-// m_offset = addr;
-// return false; // Failed to resolve this address to a section offset value
-//}
-//
Module *
Address::GetModule () const
{
@@ -309,16 +250,6 @@
return NULL;
}
-//addr_t
-//Address::Address() const
-//{
-// addr_t addr = GetLoadAddress();
-// if (addr != LLDB_INVALID_ADDRESS)
-// return addr;
-// return GetFileAddress();
-//}
-//
-
addr_t
Address::GetFileAddress () const
{
@@ -717,12 +648,6 @@
return true;
}
-//Stream& operator << (Stream& s, const Address& so_addr)
-//{
-// so_addr.Dump(&s, Address::DumpStyleSectionNameOffset);
-// return s;
-//}
-//
void
Address::CalculateSymbolContext (SymbolContext *sc)
{
@@ -795,63 +720,57 @@
}
-/// The only comparisons that make sense are the load addresses
-//bool
-//lldb::operator< (const Address& lhs, const Address& rhs)
-//{
-// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
-// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
-//
-// if (lhs_addr == rhs_addr)
-// {
-// lhs_addr = lhs.GetFileAddress();
-// rhs_addr = rhs.GetFileAddress();
-// }
-// return lhs_addr < rhs_addr;
-//}
-//
-//bool
-//lldb::operator<= (const Address& lhs, const Address& rhs)
-//{
-// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
-// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
-//
-// if (lhs_addr == rhs_addr)
-// {
-// lhs_addr = lhs.GetFileAddress();
-// rhs_addr = rhs.GetFileAddress();
-// }
-// return lhs_addr <= rhs_addr;
-//}
-//
-//bool
-//lldb::operator> (const Address& lhs, const Address& rhs)
-//{
-// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
-// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
-//
-// if (lhs_addr == rhs_addr)
-// {
-// lhs_addr = lhs.GetFileAddress();
-// rhs_addr = rhs.GetFileAddress();
-// }
-// return lhs_addr > rhs_addr;
-//}
-//
-//bool
-//lldb::operator>= (const Address& lhs, const Address& rhs)
-//{
-// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
-// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
-//
-// if (lhs_addr == rhs_addr)
-// {
-// lhs_addr = lhs.GetFileAddress();
-// rhs_addr = rhs.GetFileAddress();
-// }
-// return lhs_addr >= rhs_addr;
-//}
-//
+//----------------------------------------------------------------------
+// NOTE: Be careful using this operator. It can correctly compare two
+// addresses from the same Module correctly. It can't compare two
+// addresses from different modules in any meaningful way, but it will
+// compare the module pointers.
+//
+// To sum things up:
+// - works great for addresses within the same module
+// - it works for addresses across multiple modules, but don't expect the
+// address results to make much sense
+//
+// This basically lets Address objects be used in ordered collection
+// classes.
+//----------------------------------------------------------------------
+
+bool
+lldb_private::operator< (const Address& lhs, const Address& rhs)
+{
+ Module *lhs_module = lhs.GetModule();
+ Module *rhs_module = rhs.GetModule();
+ if (lhs_module == rhs_module)
+ {
+ // Addresses are in the same module, just compare the file addresses
+ return lhs.GetFileAddress() < rhs.GetFileAddress();
+ }
+ else
+ {
+ // The addresses are from different modules, just use the module
+ // pointer value to get consistent ordering
+ return lhs_module < rhs_module;
+ }
+}
+
+bool
+lldb_private::operator> (const Address& lhs, const Address& rhs)
+{
+ Module *lhs_module = lhs.GetModule();
+ Module *rhs_module = rhs.GetModule();
+ if (lhs_module == rhs_module)
+ {
+ // Addresses are in the same module, just compare the file addresses
+ return lhs.GetFileAddress() > rhs.GetFileAddress();
+ }
+ else
+ {
+ // The addresses are from different modules, just use the module
+ // pointer value to get consistent ordering
+ return lhs_module > rhs_module;
+ }
+}
+
// The operator == checks for exact equality only (same section, same offset)
bool
Modified: lldb/trunk/source/Symbol/FuncUnwinders.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/FuncUnwinders.cpp?rev=123045&r1=123044&r2=123045&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/FuncUnwinders.cpp (original)
+++ lldb/trunk/source/Symbol/FuncUnwinders.cpp Fri Jan 7 18:05:12 2011
@@ -24,109 +24,101 @@
using namespace lldb_private;
-FuncUnwinders::FuncUnwinders (UnwindTable& unwind_table, UnwindAssemblyProfiler *assembly_profiler, AddressRange range) :
- m_unwind_table(unwind_table),
- m_assembly_profiler(assembly_profiler),
- m_range(range),
- m_unwind_at_call_site(NULL),
- m_unwind_at_non_call_site(NULL),
- m_fast_unwind(NULL),
- m_arch_default_unwind(NULL),
- m_first_non_prologue_insn() { }
+FuncUnwinders::FuncUnwinders
+(
+ UnwindTable& unwind_table,
+ UnwindAssemblyProfiler *assembly_profiler,
+ AddressRange range
+) :
+ m_unwind_table(unwind_table),
+ m_assembly_profiler(assembly_profiler),
+ m_range(range),
+ m_unwind_at_call_site_ap (),
+ m_unwind_at_non_call_site_ap (),
+ m_fast_unwind_ap (),
+ m_arch_default_unwind (NULL),
+ m_tried_unwind_at_call_site (false),
+ m_tried_unwind_at_non_call_site (false),
+ m_tried_fast_unwind (false),
+ m_tried_arch_default_unwind (false),
+ m_first_non_prologue_insn()
+{
+}
FuncUnwinders::~FuncUnwinders ()
{
- if (m_unwind_at_call_site)
- delete m_unwind_at_call_site;
- if (m_unwind_at_non_call_site)
- delete m_unwind_at_non_call_site;
- if (m_fast_unwind)
- delete m_fast_unwind;
- if (m_arch_default_unwind)
- delete m_arch_default_unwind;
}
UnwindPlan*
FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset)
{
- if (m_unwind_at_call_site != NULL)
- return m_unwind_at_call_site;
- if (!m_range.GetBaseAddress().IsValid())
- return NULL;
-
- // We have cases (e.g. with _sigtramp on Mac OS X) where the hand-written eh_frame unwind info for a
- // function does not cover the entire range of the function and so the FDE only lists a subset of the
- // address range. If we try to look up the unwind info by the starting address of the function
- // (i.e. m_range.GetBaseAddress()) we may not find the eh_frame FDE. We need to use the actual byte offset
- // into the function when looking it up.
-
- Address current_pc (m_range.GetBaseAddress ());
- if (current_offset != -1)
- current_pc.SetOffset (current_pc.GetOffset() + current_offset);
-
- DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo();
- UnwindPlan *up = NULL;
- if (eh_frame)
+ if (m_tried_unwind_at_call_site == false && m_unwind_at_call_site_ap.get() == NULL)
{
- up = new UnwindPlan;
- if (!eh_frame->GetUnwindPlan (current_pc, *up))
+ m_tried_unwind_at_call_site = true;
+ // We have cases (e.g. with _sigtramp on Mac OS X) where the hand-written eh_frame unwind info for a
+ // function does not cover the entire range of the function and so the FDE only lists a subset of the
+ // address range. If we try to look up the unwind info by the starting address of the function
+ // (i.e. m_range.GetBaseAddress()) we may not find the eh_frame FDE. We need to use the actual byte offset
+ // into the function when looking it up.
+
+ if (m_range.GetBaseAddress().IsValid())
{
- delete up;
- return NULL;
+ Address current_pc (m_range.GetBaseAddress ());
+ if (current_offset != -1)
+ current_pc.SetOffset (current_pc.GetOffset() + current_offset);
+
+ DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo();
+ if (eh_frame)
+ {
+ m_unwind_at_call_site_ap.reset (new UnwindPlan);
+ if (!eh_frame->GetUnwindPlan (current_pc, *m_unwind_at_call_site_ap))
+ m_unwind_at_call_site_ap.reset();
+ }
}
}
- if (!up)
- return NULL;
-
- m_unwind_at_call_site = up;
- return m_unwind_at_call_site;
+ return m_unwind_at_call_site_ap.get();
}
UnwindPlan*
FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
{
- if (m_unwind_at_non_call_site != NULL)
- return m_unwind_at_non_call_site;
- UnwindPlan *up = new UnwindPlan;
- if (!m_assembly_profiler->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *up))
+ if (m_tried_unwind_at_non_call_site == false && m_unwind_at_non_call_site_ap.get() == NULL)
{
- delete up;
- return NULL;
+ m_tried_unwind_at_non_call_site = true;
+ m_unwind_at_non_call_site_ap.reset (new UnwindPlan);
+ if (!m_assembly_profiler->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_at_non_call_site_ap))
+ m_unwind_at_non_call_site_ap.reset();
}
- m_unwind_at_non_call_site = up;
- return m_unwind_at_non_call_site;
+ return m_unwind_at_non_call_site_ap.get();
}
UnwindPlan*
FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread)
{
- if (m_fast_unwind != NULL)
- return m_fast_unwind;
- UnwindPlan *up = new UnwindPlan;
- if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *up))
+ if (m_tried_fast_unwind == false && m_fast_unwind_ap.get() == NULL)
{
- delete up;
- return NULL;
+ m_tried_fast_unwind = true;
+ m_fast_unwind_ap.reset (new UnwindPlan);
+ if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_fast_unwind_ap))
+ m_fast_unwind_ap.reset();
}
- m_fast_unwind = up;
- return m_fast_unwind;
+ return m_fast_unwind_ap.get();
}
UnwindPlan*
FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread)
{
- if (m_arch_default_unwind != NULL)
- return m_arch_default_unwind;
-
- Address current_pc;
- Target *target = thread.CalculateTarget();
- if (target)
+ if (m_tried_arch_default_unwind == false && m_arch_default_unwind == NULL)
{
- ArchSpec arch = target->GetArchitecture ();
- ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch);
- if (arch_default)
+ m_tried_arch_default_unwind = true;
+ Address current_pc;
+ Target *target = thread.CalculateTarget();
+ if (target)
{
- m_arch_default_unwind = arch_default->GetArchDefaultUnwindPlan (thread, current_pc);
+ ArchSpec arch = target->GetArchitecture ();
+ ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch);
+ if (arch_default)
+ m_arch_default_unwind = arch_default->GetArchDefaultUnwindPlan (thread, current_pc);
}
}
Modified: lldb/trunk/source/Symbol/UnwindTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/UnwindTable.cpp?rev=123045&r1=123044&r2=123045&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/UnwindTable.cpp (original)
+++ lldb/trunk/source/Symbol/UnwindTable.cpp Fri Jan 7 18:05:12 2011
@@ -15,6 +15,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
+//#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -28,11 +29,12 @@
using namespace lldb;
using namespace lldb_private;
-UnwindTable::UnwindTable (ObjectFile& objfile) : m_object_file(objfile),
- m_unwinds(),
- m_initialized(false),
- m_eh_frame(NULL),
- m_assembly_profiler(NULL)
+UnwindTable::UnwindTable (ObjectFile& objfile) :
+ m_object_file (objfile),
+ m_unwinds (),
+ m_initialized (false),
+ m_eh_frame (NULL),
+ m_assembly_profiler (NULL)
{
}
@@ -40,7 +42,7 @@
// until needed for something.
void
-UnwindTable::initialize ()
+UnwindTable::Initialize ()
{
if (m_initialized)
return;
@@ -75,31 +77,21 @@
{
FuncUnwindersSP no_unwind_found;
- initialize();
+ Initialize();
- // Create a FuncUnwinders object for the binary search below
- AddressRange search_range(addr, 1);
- FuncUnwindersSP search_unwind(new FuncUnwinders (*this, NULL, search_range));
+ // There is an UnwindTable per object file, so we can safely use file handles
+ addr_t file_addr = addr.GetFileAddress();
+ iterator end = m_unwinds.end ();
+ iterator insert_pos = end;
+ if (!m_unwinds.empty())
+ {
+ insert_pos = m_unwinds.lower_bound (file_addr);
+ iterator pos = insert_pos;
+ if ((pos == m_unwinds.end ()) || (pos != m_unwinds.begin() && pos->second->GetFunctionStartAddress() != addr))
+ --pos;
- const_iterator idx;
- idx = std::lower_bound (m_unwinds.begin(), m_unwinds.end(), search_unwind);
-
- bool found_match = true;
- if (m_unwinds.size() == 0)
- {
- found_match = false;
- }
- else if (idx == m_unwinds.end())
- {
- --idx;
- }
- if (idx != m_unwinds.begin() && (*idx)->GetFunctionStartAddress().GetOffset() != addr.GetOffset())
- {
- --idx;
- }
- if (found_match && (*idx)->ContainsAddress (addr))
- {
- return *idx;
+ if (pos->second->ContainsAddress (addr))
+ return pos->second;
}
AddressRange range;
@@ -112,15 +104,29 @@
}
}
- FuncUnwindersSP unw(new FuncUnwinders(*this, m_assembly_profiler, range));
- m_unwinds.push_back (unw);
- std::sort (m_unwinds.begin(), m_unwinds.end());
- return unw;
+ FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, m_assembly_profiler, range));
+ m_unwinds.insert (insert_pos, std::make_pair(range.GetBaseAddress().GetFileAddress(), func_unwinder_sp));
+// StreamFile s(stdout);
+// Dump (s);
+ return func_unwinder_sp;
+}
+
+void
+UnwindTable::Dump (Stream &s)
+{
+ s.Printf("UnwindTable for %s/%s:\n", m_object_file.GetFileSpec().GetDirectory().GetCString(), m_object_file.GetFileSpec().GetFilename().GetCString());
+ const_iterator begin = m_unwinds.begin();
+ const_iterator end = m_unwinds.end();
+ for (const_iterator pos = begin; pos != end; ++pos)
+ {
+ s.Printf ("[%zu] 0x%16.16llx\n", std::distance (begin, pos), pos->first);
+ }
+ s.EOL();
}
DWARFCallFrameInfo *
UnwindTable::GetEHFrameInfo ()
{
- initialize();
+ Initialize();
return m_eh_frame;
}
More information about the lldb-commits
mailing list