[Lldb-commits] [lldb] r117361 - in /lldb/trunk/source: Plugins/Process/Utility/RegisterContextLLDB.cpp Plugins/Process/Utility/RegisterContextLLDB.h Symbol/DWARFCallFrameInfo.cpp

Jason Molenda jmolenda at apple.com
Tue Oct 26 05:01:35 PDT 2010


Author: jmolenda
Date: Tue Oct 26 07:01:35 2010
New Revision: 117361

URL: http://llvm.org/viewvc/llvm-project?rev=117361&view=rev
Log:
Add an unwind log Printf to note when an eh_frame section is
loaded/parsed.  Should add timers to this eventually.

Delay getting a full UnwindPlan if it's possible to unwind with
just a fast UnwindPlan.  This keeps us from reading the eh_frame
section unless we hit something built -fomit-frame pointer or we
hit a frame with no symbol (read: no start address) available.

It doesn't look like it is correctly falling back to using the
full UnwindPlan to provide additional registers that the fast
UnwindPlan doesn't supply; e.g. go to the middle of a stack and
ask for r12 and it will show you the value of r12 in frame 0.
That's a bug for tomorrow.


Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
    lldb/trunk/source/Symbol/DWARFCallFrameInfo.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=117361&r1=117360&r2=117361&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Tue Oct 26 07:01:35 2010
@@ -32,11 +32,11 @@
                                           SymbolContext& sym_ctx,
                                           int frame_number) :
     RegisterContext (thread), m_thread(thread), m_next_frame(next_frame), 
-    m_zeroth_frame(false), m_sym_ctx(sym_ctx), m_all_registers_available(false), m_registers(),
-    m_cfa (LLDB_INVALID_ADDRESS), m_start_pc (), m_frame_number (frame_number)
+    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_base_reg_ctx = m_thread.GetRegisterContext();
-    if (m_next_frame.get() == NULL)
+    if (IsFrameZero ())
     {
         InitializeZerothFrame ();
     }
@@ -44,6 +44,25 @@
     {
         InitializeNonZerothFrame ();
     }
+
+    // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet
+    bool behaves_like_zeroth_frame = false;
+    if (IsFrameZero())
+    {
+        behaves_like_zeroth_frame = true;
+    }
+    if (!IsFrameZero() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame)
+    {
+        behaves_like_zeroth_frame = true;
+    }
+    if (!IsFrameZero() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame)
+    {
+        behaves_like_zeroth_frame = true;
+    }
+    if (behaves_like_zeroth_frame)
+    {
+        m_all_registers_available = true;
+    }
 }
 
 // Initialize a RegisterContextLLDB which is the first frame of a stack -- the zeroth frame or currently
@@ -52,7 +71,6 @@
 void
 RegisterContextLLDB::InitializeZerothFrame()
 {
-    m_zeroth_frame = true;
     StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (0));
     if (m_base_reg_ctx == NULL)
     {
@@ -66,7 +84,7 @@
     else if (m_sym_ctx.symbol)
         addr_range_ptr = m_sym_ctx.symbol->GetAddressRangePtr();
 
-    Address current_pc = frame_sp->GetFrameCodeAddress();
+    m_current_pc = frame_sp->GetFrameCodeAddress();
 
     static ConstString sigtramp_name ("_sigtramp");
     if ((m_sym_ctx.function && m_sym_ctx.function->GetMangled().GetMangledName() == sigtramp_name)
@@ -89,18 +107,19 @@
     }
     else
     {
-        m_start_pc = current_pc;
+        m_start_pc = m_current_pc;
         m_current_offset = -1;
     }
 
-    // We've set m_frame_type, m_zeroth_frame, and m_sym_ctx before this call.
-    // This call sets the m_all_registers_available, m_fast_unwind_plan, and m_full_unwind_plan member variables.
-    GetUnwindPlansForFrame (current_pc);
+    // We've set m_frame_type and m_sym_ctx before these calls.
+
+    m_fast_unwind_plan = GetFastUnwindPlanForFrame ();
+    m_full_unwind_plan = GetFullUnwindPlanForFrame (); 
 
     const UnwindPlan::Row *active_row = NULL;
     int cfa_offset = 0;
     int row_register_kind;
-    if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (current_pc))
+    if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (m_current_pc))
     {
         active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
         row_register_kind = m_full_unwind_plan->GetRegisterKind ();
@@ -141,9 +160,10 @@
 
     if (log)
     {
-        log->Printf("%*sThread %d Frame %d initialized frame current pc is 0x%llx cfa is 0x%llx", 
+        log->Printf("%*sThread %d Frame %d initialized frame current pc is 0x%llx cfa is 0x%llx using %s UnwindPlan", 
                     m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
-                    (uint64_t) current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa);
+                    (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa,
+                    m_full_unwind_plan->GetSourceName().GetCString());
     }
 }
 
@@ -154,7 +174,7 @@
 RegisterContextLLDB::InitializeNonZerothFrame()
 {
     Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
-    if (m_next_frame.get() == NULL)
+    if (IsFrameZero ())
     {
         m_frame_type = eNotAValidFrame;
         return;
@@ -170,8 +190,6 @@
         return;
     }
 
-    m_zeroth_frame = false;
-    
     addr_t pc;
     if (!ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc))
     {
@@ -183,12 +201,11 @@
         m_frame_type = eNotAValidFrame;
         return;
     }
-    Address current_pc;
-    m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, current_pc);
+    m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, m_current_pc);
 
     // If we don't have a Module for some reason, we're not going to find symbol/function information - just
     // stick in some reasonable defaults and hope we can unwind past this frame.
-    if (!current_pc.IsValid() || current_pc.GetModule() == NULL)
+    if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL)
     {
         if (log)
         {
@@ -200,7 +217,7 @@
         if (arch_default)
         {
             m_fast_unwind_plan = NULL;
-            m_full_unwind_plan = arch_default->GetArchDefaultUnwindPlan (m_thread, current_pc);
+            m_full_unwind_plan = arch_default->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
             m_frame_type = eNormalFrame;
             m_all_registers_available = false;
             m_current_offset = -1;
@@ -245,7 +262,7 @@
     }
 
     // set up our m_sym_ctx SymbolContext
-    current_pc.GetModule()->ResolveSymbolContextForAddress (current_pc, eSymbolContextFunction | eSymbolContextSymbol, m_sym_ctx);
+    m_current_pc.GetModule()->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction | eSymbolContextSymbol, m_sym_ctx);
 
     const AddressRange *addr_range_ptr;
     if (m_sym_ctx.function)
@@ -270,30 +287,37 @@
     if (addr_range_ptr)
     {
         m_start_pc = addr_range_ptr->GetBaseAddress();
-        m_current_offset = current_pc.GetOffset() - m_start_pc.GetOffset();
+        m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
     }
     else
     {
-        m_start_pc = current_pc;
+        m_start_pc = m_current_pc;
         m_current_offset = -1;
     }
 
-    // We've set m_frame_type, m_zeroth_frame, and m_sym_ctx before this call.
-    // This call sets the m_all_registers_available, m_fast_unwind_plan, and m_full_unwind_plan member variables.
-    GetUnwindPlansForFrame (current_pc);
+    // We've set m_frame_type and m_sym_ctx before this call.
+    m_fast_unwind_plan = GetFastUnwindPlanForFrame ();
 
     const UnwindPlan::Row *active_row = NULL;
     int cfa_offset = 0;
     int row_register_kind;
-    if (m_fast_unwind_plan && m_fast_unwind_plan->PlanValidAtAddress (current_pc))
+
+    // Try to get by with just the fast UnwindPlan if possible - the full UnwindPlan may be expensive to get
+    // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for the first time.)
+
+    if (m_fast_unwind_plan && m_fast_unwind_plan->PlanValidAtAddress (m_current_pc))
     {
         active_row = m_fast_unwind_plan->GetRowForFunctionOffset (m_current_offset);
         row_register_kind = m_fast_unwind_plan->GetRegisterKind ();
     }
-    else if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (current_pc))
+    else 
     {
-        active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
-        row_register_kind = m_full_unwind_plan->GetRegisterKind ();
+        m_full_unwind_plan = GetFullUnwindPlanForFrame ();
+        if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (m_current_pc))
+        {
+            active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
+            row_register_kind = m_full_unwind_plan->GetRegisterKind ();
+        }
     }
 
     if (active_row == NULL)
@@ -334,171 +358,194 @@
     {
         log->Printf("%*sFrame %d initialized frame current pc is 0x%llx cfa is 0x%llx", 
                     m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                    (uint64_t) current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa);
+                    (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa);
     }
 }
 
 
+bool
+RegisterContextLLDB::IsFrameZero () const
+{
+    if (m_next_frame.get () == NULL)
+        return true;
+    else
+        return false;
+}
 
 
-// On entry to this method, 
-//
-//   1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame 
-//      if either of those are correct, and
-//   2. m_zeroth_frame should be set to true if this is frame 0 and
-//   3. m_sym_ctx should already be filled in.
+// Find a fast unwind plan for this frame, if possible.
 //
-// On exit this function will have set
+// On entry to this method, 
 //
-//   a. m_all_registers_available  (true if we can provide any requested register, false if only a subset are provided)
-//   b. m_fast_unwind_plan (fast unwind plan that walks the stack while filling in only minimal registers, may be NULL)
-//   c. m_full_unwind_plan (full unwind plan that can provide all registers possible, will *not* be NULL)
+//   1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct, 
+//   2. m_sym_ctx should already be filled in, and
+//   3. m_current_pc should have the current pc value for this frame
+
+UnwindPlan *
+RegisterContextLLDB::GetFastUnwindPlanForFrame ()
+{
+    if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL)
+    {
+        return NULL;
+    }
+
+    if (IsFrameZero ())
+    {
+        return NULL;
+    }
+
+    FuncUnwindersSP fu;
+    fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
+    if (fu.get() == NULL)
+    {
+        return NULL;
+    }
+
+    // If we're in _sigtramp(), unwinding past this frame requires special knowledge.  
+    if (m_frame_type == eSigtrampFrame || m_frame_type == eDebuggerFrame)
+    {
+        return NULL;
+    }
+
+    if (fu->GetUnwindPlanFastUnwind (m_thread) 
+        && fu->GetUnwindPlanFastUnwind (m_thread)->PlanValidAtAddress (m_current_pc))
+    {
+        Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
+        if (log && IsLogVerbose())
+        {
+            const char *has_fast = "";
+            if (m_fast_unwind_plan)
+                has_fast = ", and has a fast UnwindPlan";
+            log->Printf("%*sFrame %d frame has a fast UnwindPlan",
+                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
+        }
+        m_frame_type = eNormalFrame;
+        return fu->GetUnwindPlanFastUnwind (m_thread);
+    }
+
+    return NULL;
+}
+
+// On entry to this method, 
 //
-// The argument current_pc should be the current pc value in the function.  
+//   1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct, 
+//   2. m_sym_ctx should already be filled in, and
+//   3. m_current_pc should have the current pc value for this frame
 
-void
-RegisterContextLLDB::GetUnwindPlansForFrame (Address current_pc)
+UnwindPlan *
+RegisterContextLLDB::GetFullUnwindPlanForFrame ()
 {
+    Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
+    UnwindPlan *up;
     UnwindPlan *arch_default_up = NULL;
     ArchSpec arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
     ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch);
     if (arch_default)
     {
-        arch_default_up = arch_default->GetArchDefaultUnwindPlan (m_thread, current_pc);
+        arch_default_up = arch_default->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
     }
 
     bool behaves_like_zeroth_frame = false;
-
-    if (m_zeroth_frame)
+    if (IsFrameZero ())
     {
         behaves_like_zeroth_frame = true;
     }
-    if (m_next_frame.get() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame)
+    if (!IsFrameZero () && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame)
     {
         behaves_like_zeroth_frame = true;
     }
-    if (m_next_frame.get() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame)
+    if (!IsFrameZero () && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame)
     {
         behaves_like_zeroth_frame = true;
     }
-
     if (behaves_like_zeroth_frame)
     {
         m_all_registers_available = true;
     }
-    else
-    {
-//        If we need to implement gdb's decrement-pc-value-by-one-before-function-check macro, it would be here.
-//        current_pc.SetOffset (current_pc.GetOffset() - 1);
-        m_all_registers_available = false;
-    }
 
     // No Module for the current pc, try using the architecture default unwind.
-    if (current_pc.GetModule() == NULL || current_pc.GetModule()->GetObjectFile() == NULL)
+    if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL)
     {
-        m_fast_unwind_plan = NULL;
-        m_full_unwind_plan = arch_default_up;
         m_frame_type = eNormalFrame;
-        return;
+        return arch_default_up;
     }
 
     FuncUnwindersSP fu;
-    if (current_pc.GetModule() && current_pc.GetModule()->GetObjectFile())
-    {
-       fu = current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (current_pc, m_sym_ctx);
-    }
+    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)
     {
-        m_fast_unwind_plan = NULL;
-        m_full_unwind_plan = arch_default_up;
         m_frame_type = eNormalFrame;
-        return;
+        return arch_default_up;
     }
 
     // If we're in _sigtramp(), unwinding past this frame requires special knowledge.  On Mac OS X this knowledge
     // is properly encoded in the eh_frame section, so prefer that if available.
+    // On other platforms we may need to provide a platform-specific UnwindPlan which encodes the details of
+    // how to unwind out of sigtramp.
     if (m_frame_type == eSigtrampFrame)
     {
         m_fast_unwind_plan = NULL;
         UnwindPlan *up = fu->GetUnwindPlanAtCallSite ();
-        if (up->PlanValidAtAddress (current_pc))
+        if (up->PlanValidAtAddress (m_current_pc))
         {
-            m_fast_unwind_plan = NULL;
-            m_full_unwind_plan = up;
-            return;
+            return up;
         }
     }
 
-
-    UnwindPlan *fast, *callsite, *noncallsite;
-    fast = callsite = noncallsite = NULL;
-
-    if (fu->GetUnwindPlanFastUnwind (m_thread) 
-        && fu->GetUnwindPlanFastUnwind (m_thread)->PlanValidAtAddress (current_pc))
-    {
-        fast = fu->GetUnwindPlanFastUnwind (m_thread);
-    }
-
-    // Typically this is the unwind created by inspecting the assembly language instructions
-    if (fu->GetUnwindPlanAtNonCallSite (m_thread) 
-        && fu->GetUnwindPlanAtNonCallSite (m_thread)->PlanValidAtAddress (current_pc))
+    
+    // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions
+    up = fu->GetUnwindPlanAtNonCallSite (m_thread);
+    if (behaves_like_zeroth_frame && up && up->PlanValidAtAddress (m_current_pc))
     {
-        noncallsite = fu->GetUnwindPlanAtNonCallSite (m_thread);
+        if (log && IsLogVerbose())
+        {
+            log->Printf("%*sFrame %d frame uses %s for full UnwindPlan",
+                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                        up->GetSourceName().GetCString());
+        }
+        return up;
     }
 
-
     // Typically this is unwind info from an eh_frame section intended for exception handling; only valid at call sites
-    if (fu->GetUnwindPlanAtCallSite () 
-        && fu->GetUnwindPlanAtCallSite ()->PlanValidAtAddress (current_pc))
-    {
-        callsite = fu->GetUnwindPlanAtCallSite ();
-    }
-
-    m_fast_unwind_plan = NULL;
-    m_full_unwind_plan = NULL;
-
-    if (fast)
-    {
-        m_fast_unwind_plan = fast;
-    }
-
-    if (behaves_like_zeroth_frame && noncallsite)
-    {
-        m_full_unwind_plan = noncallsite;
-    }
-    else 
+    up = fu->GetUnwindPlanAtCallSite ();
+    if (up && up->PlanValidAtAddress (m_current_pc))
     {
-        if (callsite)
+        if (log && IsLogVerbose())
         {
-            m_full_unwind_plan = callsite;
-        }
-        else
-        {
-            m_full_unwind_plan = noncallsite;
+            log->Printf("%*sFrame %d frame uses %s for full UnwindPlan",
+                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                        up->GetSourceName().GetCString());
         }
+        return up;
     }
-
-    if (m_full_unwind_plan == NULL)
+    
+    // We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've
+    // struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible.
+    up = fu->GetUnwindPlanAtNonCallSite (m_thread);
+    if (up && up->PlanValidAtAddress (m_current_pc))
     {
-        m_full_unwind_plan = arch_default_up;
+        if (log && IsLogVerbose())
+        {
+            log->Printf("%*sFrame %d frame uses %s for full UnwindPlan",
+                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                        up->GetSourceName().GetCString());
+        }
+        return up;
     }
 
-    Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
+    // If nothing else, use the architectural default UnwindPlan and hope that does the job.
     if (log && IsLogVerbose())
     {
-        const char *has_fast = "";
-        if (m_fast_unwind_plan)
-            has_fast = ", and has a fast UnwindPlan";
-        log->Printf("%*sFrame %d frame uses %s for full UnwindPlan%s",
+        log->Printf("%*sFrame %d frame uses %s for full UnwindPlan",
                     m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                    m_full_unwind_plan->GetSourceName().GetCString(), has_fast);
+                    arch_default_up->GetSourceName().GetCString());
     }
-
-    return;
+    return arch_default_up;
 }
 
+
 void
 RegisterContextLLDB::Invalidate ()
 {
@@ -545,7 +592,7 @@
     {
         data.SetAddressByteSize (m_thread.GetProcess().GetAddressByteSize());
         data.SetByteOrder (m_thread.GetProcess().GetByteOrder());
-        if (m_next_frame.get() == NULL)
+        if (IsFrameZero ())
         {
             return m_base_reg_ctx->ReadRegisterBytes (regloc.location.register_number, data);
         }
@@ -660,11 +707,14 @@
 
     UnwindPlan::Row::RegisterLocation unwindplan_regloc;
     bool have_unwindplan_regloc = false;
+    int unwindplan_registerkind;
+
     if (m_fast_unwind_plan)
     {
         const UnwindPlan::Row *active_row = m_fast_unwind_plan->GetRowForFunctionOffset (m_current_offset);
+        unwindplan_registerkind = m_fast_unwind_plan->GetRegisterKind ();
         uint32_t row_regnum;
-        if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, m_fast_unwind_plan->GetRegisterKind(), row_regnum))
+        if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
         {
             if (log)
             {
@@ -685,29 +735,38 @@
             have_unwindplan_regloc = true;
         }
     }
-    else if (m_full_unwind_plan)
+    else
     {
-        const UnwindPlan::Row *active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
-        uint32_t row_regnum;
-        if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, m_full_unwind_plan->GetRegisterKind(), row_regnum))
+        // m_full_unwind_plan being NULL probably means that we haven't tried to find a full UnwindPlan yet
+        if (m_full_unwind_plan == NULL)
         {
-            if (log)
+            m_full_unwind_plan = GetFullUnwindPlanForFrame ();
+        }
+        if (m_full_unwind_plan)
+        {
+            const UnwindPlan::Row *active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
+            unwindplan_registerkind = m_full_unwind_plan->GetRegisterKind ();
+            uint32_t row_regnum;
+            if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
             {
-                log->Printf("%*sFrame %d could not supply caller's reg %d location",
-                            m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                            lldb_regnum);
+                if (log)
+                {
+                    log->Printf("%*sFrame %d could not supply caller's reg %d location",
+                                m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                                lldb_regnum);
+                }
+                return false;
             }
-            return false;
-        }
 
-        if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
-        {
-            have_unwindplan_regloc = true;
-            if (log && IsLogVerbose ())
-            {                
-                log->Printf("%*sFrame %d supplying caller's saved reg %d's location using %s UnwindPlan",
-                            m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                            lldb_regnum, m_full_unwind_plan->GetSourceName().GetCString());
+            if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
+            {
+                have_unwindplan_regloc = true;
+                if (log && IsLogVerbose ())
+                {                
+                    log->Printf("%*sFrame %d supplying caller's saved reg %d's location using %s UnwindPlan",
+                                m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                                lldb_regnum, m_full_unwind_plan->GetSourceName().GetCString());
+                }
             }
         }
     }
@@ -728,7 +787,7 @@
             return false;
         }  
 
-        if (m_next_frame.get())
+        if (!IsFrameZero ())
         {
             return ((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc);
         }
@@ -768,7 +827,7 @@
 
     if (unwindplan_regloc.IsSame())
     {
-        if (m_next_frame.get())
+        if (!IsFrameZero ())
         {
             return ((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc);
         }
@@ -806,7 +865,7 @@
     {
         uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
         uint32_t row_regnum_in_lldb;
-        if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (m_full_unwind_plan->GetRegisterKind(), unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb))
+        if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (unwindplan_registerkind, unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb))
         {
             if (log)
             {
@@ -870,7 +929,7 @@
     data.SetByteOrder (m_thread.GetProcess().GetByteOrder());
 
     // if this is frame 0 (currently executing frame), get the requested reg contents from the actual thread registers
-    if (m_next_frame.get() == NULL)
+    if (IsFrameZero ())
     {
         if (m_base_reg_ctx->ReadRegisterBytes (lldb_regnum, data))
         {
@@ -915,7 +974,7 @@
     }
 
     // If this is the 0th frame, hand this over to the live register context
-    if (m_next_frame.get() == NULL)
+    if (IsFrameZero ())
     {
         if (log)
         {

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=117361&r1=117360&r2=117361&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h Tue Oct 26 07:01:35 2010
@@ -106,6 +106,14 @@
     };
 
 
+    // Indicates whether this frame is frame zero -- the currently
+    // executing frame -- or not.  If it is not frame zero, m_next_frame's
+    // shared pointer holds a pointer to the RegisterContextLLDB
+    // object "below" this frame, i.e. this frame called m_next_frame's
+    // function.
+    bool
+    IsFrameZero () const;
+
     void 
     InitializeZerothFrame ();
 
@@ -139,8 +147,11 @@
     bool
     ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value);
 
-    void
-    GetUnwindPlansForFrame (lldb_private::Address current_pc);
+    lldb_private::UnwindPlan *
+    GetFastUnwindPlanForFrame ();
+
+    lldb_private::UnwindPlan *
+    GetFullUnwindPlanForFrame ();
 
     lldb_private::Thread& m_thread;
     lldb::RegisterContextSP m_next_frame;
@@ -154,7 +165,6 @@
 
     lldb_private::UnwindPlan *m_fast_unwind_plan;    // may be NULL
     lldb_private::UnwindPlan *m_full_unwind_plan;
-    bool m_zeroth_frame;                             // Is this the bottom-most, i.e. currently executing, frame?
     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
@@ -164,6 +174,7 @@
 
     lldb::addr_t m_cfa;
     lldb_private::Address m_start_pc;
+    lldb_private::Address m_current_pc;
 
     std::map<uint32_t, RegisterLocation> m_registers; // where to find reg values for this frame
 

Modified: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp?rev=117361&r1=117360&r2=117361&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp Tue Oct 26 07:01:35 2010
@@ -12,6 +12,7 @@
 // C++ Includes
 #include <list>
 
+#include "lldb/Core/Log.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/DWARFCallFrameInfo.h"
 #include "lldb/Core/ArchSpec.h"
@@ -284,9 +285,15 @@
     if (m_fde_index_initialized)
         return;
 
+
     dw_offset_t offset = 0;
     if (m_cfi_data_initialized == false)
     {
+        Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
+        if (log)
+        { 
+            log->Printf ("Reading eh_frame information for %s", m_objfile.GetFileSpec().GetFilename().GetCString());
+        }
         m_section->ReadSectionDataFromObjectFile (&m_objfile, m_cfi_data);
         m_cfi_data_initialized = true;
     }





More information about the lldb-commits mailing list