[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