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.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@123045 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Symbol/UnwindTable.cpp b/source/Symbol/UnwindTable.cpp
index 5356e94..697098d 100644
--- a/source/Symbol/UnwindTable.cpp
+++ b/source/Symbol/UnwindTable.cpp
@@ -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;
}