[Lldb-commits] [lldb] r118218 - in /lldb/trunk/source: Plugins/Process/Utility/RegisterContextLLDB.cpp Plugins/Process/Utility/RegisterContextLLDB.h Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp Plugins/Process/Utility/UnwindLLDB.cpp Plugins/Process/Utility/UnwindLLDB.h Symbol/UnwindPlan.cpp Symbol/UnwindTable.cpp

Jason Molenda jmolenda at apple.com
Wed Nov 3 17:53:20 PDT 2010


Author: jmolenda
Date: Wed Nov  3 19:53:20 2010
New Revision: 118218

URL: http://llvm.org/viewvc/llvm-project?rev=118218&view=rev
Log:
Handle the case where no eh_frame section is present.

RegisterContextLLDB holds a reference to the SymbolContext
in the vector of Cursors that UnwindLLDB maintains.  Switch
UnwindLLDB to hold a vector of shared pointers of Cursors
so this reference doesn't become invalid.

Correctly falling back from the "fast" UnwindPlan to the
"full" UnwindPlan when additional registers need to be
retrieved.

Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
    lldb/trunk/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h
    lldb/trunk/source/Symbol/UnwindPlan.cpp
    lldb/trunk/source/Symbol/UnwindTable.cpp

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=118218&r1=118217&r2=118218&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Wed Nov  3 19:53:20 2010
@@ -33,9 +33,13 @@
                                           int frame_number) :
     RegisterContext (thread), m_thread(thread), m_next_frame(next_frame), 
     m_sym_ctx(sym_ctx), m_all_registers_available(false), m_registers(),
-    m_cfa (LLDB_INVALID_ADDRESS), m_start_pc (), m_current_pc (), m_frame_number (frame_number)
+    m_cfa (LLDB_INVALID_ADDRESS), m_start_pc (), m_current_pc (), m_frame_number (frame_number),
+    m_full_unwind_plan(NULL), m_fast_unwind_plan(NULL)
 {
+    m_sym_ctx.Clear();
+    m_sym_ctx_valid = false;
     m_base_reg_ctx = m_thread.GetRegisterContext();
+
     if (IsFrameZero ())
     {
         InitializeZerothFrame ();
@@ -77,13 +81,11 @@
         m_frame_type = eNotAValidFrame;
         return;
     }
-    m_sym_ctx = frame_sp->GetSymbolContext (eSymbolContextEverything);
-    const AddressRange *addr_range_ptr;
-    if (m_sym_ctx.function)
-        addr_range_ptr = &m_sym_ctx.function->GetAddressRange();
-    else if (m_sym_ctx.symbol)
-        addr_range_ptr = m_sym_ctx.symbol->GetAddressRangePtr();
-
+    m_sym_ctx = frame_sp->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
+    m_sym_ctx_valid = true;
+    AddressRange addr_range;
+    m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, addr_range);
+    
     m_current_pc = frame_sp->GetFrameCodeAddress();
 
     static ConstString sigtramp_name ("_sigtramp");
@@ -98,11 +100,11 @@
         m_frame_type = eNormalFrame;
     }
 
-    // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function.
+    // If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function.
     // else treat the current pc value as the start_pc and record no offset.
-    if (addr_range_ptr)
+    if (addr_range.GetBaseAddress().IsValid())
     {
-        m_start_pc = addr_range_ptr->GetBaseAddress();
+        m_start_pc = addr_range.GetBaseAddress();
         m_current_offset = frame_sp->GetFrameCodeAddress().GetOffset() - m_start_pc.GetOffset();
     }
     else
@@ -261,14 +263,17 @@
         return;
     }
 
-    // set up our m_sym_ctx SymbolContext
-    m_current_pc.GetModule()->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction | eSymbolContextSymbol, m_sym_ctx);
+    // We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us.
+    if ((m_current_pc.GetModule()->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol)
+    {
+        m_sym_ctx_valid = true;
+    }
 
-    const AddressRange *addr_range_ptr;
-    if (m_sym_ctx.function)
-        addr_range_ptr = &m_sym_ctx.function->GetAddressRange();
-    else if (m_sym_ctx.symbol)
-        addr_range_ptr = m_sym_ctx.symbol->GetAddressRangePtr();
+    AddressRange addr_range;
+    if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, addr_range))
+    {
+        m_sym_ctx_valid = false;
+    }
 
     static ConstString sigtramp_name ("_sigtramp");
     if ((m_sym_ctx.function && m_sym_ctx.function->GetMangled().GetMangledName() == sigtramp_name)
@@ -284,9 +289,9 @@
 
     // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function.
     // else treat the current pc value as the start_pc and record no offset.
-    if (addr_range_ptr)
+    if (addr_range.GetBaseAddress().IsValid())
     {
-        m_start_pc = addr_range_ptr->GetBaseAddress();
+        m_start_pc = addr_range.GetBaseAddress();
         m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
     }
     else
@@ -458,6 +463,9 @@
     {
         behaves_like_zeroth_frame = true;
     }
+
+    // If this frame behaves like a 0th frame (currently executing or interrupted asynchronously), all registers
+    // can be retrieved.
     if (behaves_like_zeroth_frame)
     {
         m_all_registers_available = true;
@@ -471,7 +479,10 @@
     }
 
     FuncUnwindersSP fu;
-    fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
+    if (m_sym_ctx_valid)
+    {
+        fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
+    }
 
     // No FuncUnwinders available for this pc, try using architectural default unwind.
     if (fu.get() == NULL)
@@ -718,9 +729,9 @@
         {
             if (log)
             {
-                log->Printf("%*sFrame %d could not supply caller's reg %d location",
+                log->Printf("%*sFrame %d could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
                             m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                            lldb_regnum);
+                            lldb_regnum, (int) unwindplan_registerkind);
             }
             return false;
         }
@@ -735,9 +746,10 @@
             have_unwindplan_regloc = true;
         }
     }
-    else
+
+    if (!have_unwindplan_regloc)
     {
-        // m_full_unwind_plan being NULL probably means that we haven't tried to find a full UnwindPlan yet
+        // m_full_unwind_plan being NULL means that we haven't tried to find a full UnwindPlan yet
         if (m_full_unwind_plan == NULL)
         {
             m_full_unwind_plan = GetFullUnwindPlanForFrame ();
@@ -751,9 +763,9 @@
             {
                 if (log)
                 {
-                    log->Printf("%*sFrame %d could not supply caller's reg %d location",
+                    log->Printf("%*sFrame %d could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
                                 m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                                lldb_regnum);
+                                lldb_regnum, (int) unwindplan_registerkind);
                 }
                 return false;
             }
@@ -770,6 +782,7 @@
             }
         }
     }
+
     if (have_unwindplan_regloc == false)
     {
         // If a volatile register is being requested, we don't want to forward m_next_frame's register contents 

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h?rev=118218&r1=118217&r2=118218&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h Wed Nov  3 19:53:20 2010
@@ -163,14 +163,15 @@
     // i.e. where THIS frame saved them
     ///
 
-    lldb_private::UnwindPlan *m_fast_unwind_plan;    // may be NULL
+    lldb_private::UnwindPlan *m_fast_unwind_plan;  // may be NULL
     lldb_private::UnwindPlan *m_full_unwind_plan;
-    bool m_all_registers_available;                  // Can we retrieve all regs or just nonvolatile regs?
-    int m_frame_type;                                // enum FrameType
-    int m_current_offset;                            // how far into the function we've executed; -1 if unknown
+    bool m_all_registers_available;               // Can we retrieve all regs or just nonvolatile regs?
+    int m_frame_type;                             // enum FrameType
+    int m_current_offset;                         // how far into the function we've executed; -1 if unknown
     lldb_private::SymbolContext& m_sym_ctx;
+    bool m_sym_ctx_valid;                         // if ResolveSymbolContextForAddress fails, don't try to use m_sym_ctx
 
-    int m_frame_number;                              // What stack frame level this frame is - used for debug logging
+    int m_frame_number;                           // What stack frame level this frame is - used for debug logging
 
     lldb::addr_t m_cfa;
     lldb_private::Address m_start_pc;

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp?rev=118218&r1=118217&r2=118218&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp Wed Nov  3 19:53:20 2010
@@ -478,6 +478,10 @@
 AssemblyParse_x86::instruction_length (Address addr, int &length)
 {
     const char *triple;
+
+    if (!addr.IsValid())
+        return false;
+
     // FIXME should probably pass down the ArchSpec and work from that to make a portable triple
     if (m_cpu == k_i386)
         triple = "i386-unknown-unknown";
@@ -512,11 +516,16 @@
     UnwindPlan up;
     UnwindPlan::Row row;
     int non_prologue_insn_count = 0;
-    Address m_cur_insn = m_func_bounds.GetBaseAddress ();
+    m_cur_insn = m_func_bounds.GetBaseAddress ();
     int current_func_text_offset = 0;
     int current_sp_bytes_offset_from_cfa = 0;
     UnwindPlan::Row::RegisterLocation regloc;
 
+    if (!m_cur_insn.IsValid())
+    {
+        return false;
+    }
+
     unwind_plan.SetPlanValidAddressRange (m_func_bounds);
     unwind_plan.SetRegisterKind (eRegisterKindLLDB);
 
@@ -725,6 +734,11 @@
 AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
 {
     m_cur_insn = m_func_bounds.GetBaseAddress ();
+    if (!m_cur_insn.IsValid())
+    {
+        return false;
+    }
+
     while (m_func_bounds.ContainsFileAddress (m_cur_insn))
     {
         Error error;

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp?rev=118218&r1=118217&r2=118218&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp Wed Nov  3 19:53:20 2010
@@ -35,20 +35,20 @@
     if (m_frames.empty())
     {
         // First, set up the 0th (initial) frame
-        Cursor first_cursor;
+        CursorSP first_cursor_sp(new Cursor);
         RegisterContextSP no_frame; // an empty shared pointer
-        RegisterContextLLDB *first_register_ctx = new RegisterContextLLDB(m_thread, no_frame, first_cursor.sctx, 0);
+        RegisterContextLLDB *first_register_ctx = new RegisterContextLLDB(m_thread, no_frame, first_cursor_sp->sctx, 0);
         if (!first_register_ctx->IsValid())
         {
             delete first_register_ctx;
             return 0;
         }
-        if (!first_register_ctx->GetCFA (first_cursor.cfa))
+        if (!first_register_ctx->GetCFA (first_cursor_sp->cfa))
         {
             delete first_register_ctx;
             return 0;
         }
-        if (!first_register_ctx->GetPC (first_cursor.start_pc))
+        if (!first_register_ctx->GetPC (first_cursor_sp->start_pc))
         {
             delete first_register_ctx;
             return 0;
@@ -56,16 +56,16 @@
         // Reuse the StackFrame provided by the processor native machine context for the first frame
         first_register_ctx->SetStackFrame (m_thread.GetStackFrameAtIndex(0).get());
         RegisterContextSP temp_rcs(first_register_ctx);
-        first_cursor.reg_ctx = temp_rcs;
-        m_frames.push_back (first_cursor);
+        first_cursor_sp->reg_ctx = temp_rcs;
+        m_frames.push_back (first_cursor_sp);
 
         // Now walk up the rest of the stack
         while (1)
         {
-            Cursor cursor;
+            CursorSP cursor_sp(new Cursor);
             RegisterContextLLDB *register_ctx;
             int cur_idx = m_frames.size ();
-            register_ctx = new RegisterContextLLDB (m_thread, m_frames[cur_idx - 1].reg_ctx, cursor.sctx, cur_idx);
+            register_ctx = new RegisterContextLLDB (m_thread, m_frames[cur_idx - 1]->reg_ctx, cursor_sp->sctx, cur_idx);
             if (!register_ctx->IsValid())
             {
                 delete register_ctx;
@@ -76,7 +76,7 @@
                 }
                 break;
             }
-            if (!register_ctx->GetCFA (cursor.cfa))
+            if (!register_ctx->GetCFA (cursor_sp->cfa))
             {
                 delete register_ctx;
                 if (log)
@@ -86,7 +86,7 @@
                 }
                 break;
             }
-            if (cursor.cfa == (addr_t) -1 || cursor.cfa == 1 || cursor.cfa == 0)
+            if (cursor_sp->cfa == (addr_t) -1 || cursor_sp->cfa == 1 || cursor_sp->cfa == 0)
             {
                 delete register_ctx;
                 if (log)
@@ -96,7 +96,7 @@
                 }
                 break;
             }
-            if (!register_ctx->GetPC (cursor.start_pc))
+            if (!register_ctx->GetPC (cursor_sp->start_pc))
             {
                 delete register_ctx;
                 if (log)
@@ -107,10 +107,10 @@
                 break;
             }
             RegisterContextSP temp_rcs(register_ctx);
-            StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, temp_rcs, cursor.cfa, cursor.start_pc, &cursor.sctx);
+            StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, temp_rcs, cursor_sp->cfa, cursor_sp->start_pc, &(cursor_sp->sctx));
             register_ctx->SetStackFrame (frame);
-            cursor.reg_ctx = temp_rcs;
-            m_frames.push_back (cursor);
+            cursor_sp->reg_ctx = temp_rcs;
+            m_frames.push_back (cursor_sp);
         }
     }
     return m_frames.size ();
@@ -125,8 +125,8 @@
 
     if (idx < m_frames.size ())
     {
-        cfa = m_frames[idx].cfa;
-        pc = m_frames[idx].start_pc;
+        cfa = m_frames[idx]->cfa;
+        pc = m_frames[idx]->start_pc;
         return true;
     }
     return false;
@@ -146,6 +146,6 @@
         return m_thread.GetRegisterContext();
     }
     if (idx < m_frames.size ())
-        return m_frames[idx].reg_ctx.get();
+        return m_frames[idx]->reg_ctx.get();
     return NULL;
 }

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h?rev=118218&r1=118217&r2=118218&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h Wed Nov  3 19:53:20 2010
@@ -11,6 +11,7 @@
 #define lldb_UnwindLLDB_h_
 
 #include "lldb/lldb-private.h"
+#include "lldb/lldb-types.h"
 #include "lldb/Target/Unwind.h"
 #include "lldb/Symbol/FuncUnwinders.h"
 #include "lldb/Symbol/UnwindPlan.h"
@@ -57,7 +58,8 @@
         Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx() { }
     };
 
-    std::vector<Cursor> m_frames;
+    typedef lldb::SharedPtr<Cursor>::Type CursorSP;
+    std::vector<CursorSP> m_frames;
 
     //------------------------------------------------------------------
     // For UnwindLLDB only

Modified: lldb/trunk/source/Symbol/UnwindPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/UnwindPlan.cpp?rev=118218&r1=118217&r2=118218&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/UnwindPlan.cpp (original)
+++ lldb/trunk/source/Symbol/UnwindPlan.cpp Wed Nov  3 19:53:20 2010
@@ -287,6 +287,9 @@
     if (!m_plan_valid_address_range.GetBaseAddress().IsValid() || m_plan_valid_address_range.GetByteSize() == 0)
         return true;
 
+    if (!addr.IsValid())
+        return true;
+
     if (m_plan_valid_address_range.ContainsFileAddress (addr))
         return true;
 

Modified: lldb/trunk/source/Symbol/UnwindTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/UnwindTable.cpp?rev=118218&r1=118217&r2=118218&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/UnwindTable.cpp (original)
+++ lldb/trunk/source/Symbol/UnwindTable.cpp Wed Nov  3 19:53:20 2010
@@ -77,6 +77,11 @@
 
     initialize();
 
+    if (m_eh_frame == NULL)
+    {
+        return no_unwind_found;
+    }
+
     // Create a FuncUnwinders object for the binary search below
     AddressRange search_range(addr, 1);
     FuncUnwindersSP search_unwind(new FuncUnwinders (*this, NULL, search_range));
@@ -103,26 +108,19 @@
     }
 
     AddressRange range;
-    if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
+    if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range) || !range.GetBaseAddress().IsValid())
     {
-        FuncUnwindersSP unw(new FuncUnwinders(*this, m_assembly_profiler, range));
-        m_unwinds.push_back (unw);
-        std::sort (m_unwinds.begin(), m_unwinds.end());
-        return unw;
-    }
-    else
-    {
-        // Does the eh_frame unwind info has a function bounds defined for this addr?
-        if (m_eh_frame->GetAddressRange (addr, range))
+        // Does the eh_frame unwind info has a function bounds for this addr?
+        if (!m_eh_frame->GetAddressRange (addr, range))
         {
-            FuncUnwindersSP unw(new FuncUnwinders(*this, m_assembly_profiler, range));
-            m_unwinds.push_back (unw);
-            std::sort (m_unwinds.begin(), m_unwinds.end());
-            return unw;
-            // FIXME we should create a syntheic Symbol based on the address range with a synthesized symbol name
+            return no_unwind_found;
         }
     }
-    return no_unwind_found;
+
+    FuncUnwindersSP unw(new FuncUnwinders(*this, m_assembly_profiler, range));
+    m_unwinds.push_back (unw);
+    std::sort (m_unwinds.begin(), m_unwinds.end());
+    return unw;
 }
 
 DWARFCallFrameInfo *





More information about the lldb-commits mailing list