[Lldb-commits] [lldb] r118477 - in /lldb/trunk/source/Plugins/Process/Utility: UnwindLLDB.cpp UnwindLLDB.h

Jason Molenda jmolenda at apple.com
Mon Nov 8 18:31:21 PST 2010


Author: jmolenda
Date: Mon Nov  8 20:31:21 2010
New Revision: 118477

URL: http://llvm.org/viewvc/llvm-project?rev=118477&view=rev
Log:
Refactor UnwindLLDB so it doesn't populate the entire stack unless
the frame count is requested or each frame is individually requested.

In practice this doesn't seem to help anything because we have
functions like StackFrameList::GetNumFrames() which is going to
request each frame anyway.  And classes like ThreadPlanStepRange
and ThreadPlanStepOverRange get the stack depth in their ctor forcing
a full stack walk.  But at least UnwindLLDB will delay doing a full
walk if it can.


Modified:
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h

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=118477&r1=118476&r2=118477&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp Mon Nov  8 20:31:21 2010
@@ -31,97 +31,120 @@
 uint32_t
 UnwindLLDB::GetFrameCount()
 {
-    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
     if (m_frames.empty())
     {
-        // First, set up the 0th (initial) frame
-        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_sp->sctx, 0);
-        if (!first_register_ctx->IsValid())
-        {
-            delete first_register_ctx;
+        if (!AddFirstFrame ())
             return 0;
+        while (AddOneMoreFrame ())
+            ;
+    }
+    return m_frames.size ();
+}
+
+bool
+UnwindLLDB::AddFirstFrame ()
+{
+    // First, set up the 0th (initial) frame
+    CursorSP first_cursor_sp(new Cursor ());
+    RegisterContextSP no_frame; 
+    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 false;
+    }
+    if (!first_register_ctx->GetCFA (first_cursor_sp->cfa))
+    {
+        delete first_register_ctx;
+        return false;
+    }
+    if (!first_register_ctx->GetPC (first_cursor_sp->start_pc))
+    {
+        delete first_register_ctx;
+        return false;
+    }
+    // Reuse the StackFrame provided by the processor native machine context for the first frame
+    first_register_ctx->SetStackFrame (m_thread.GetStackFrameAtIndex(0).get());
+    RegisterContextSP first_register_ctx_sp(first_register_ctx);
+    first_cursor_sp->reg_ctx = first_register_ctx_sp;
+    m_frames.push_back (first_cursor_sp);
+    return true;
+}
+
+// For adding a non-zero stack frame to m_frames.
+bool
+UnwindLLDB::AddOneMoreFrame ()
+{
+    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+    CursorSP cursor_sp(new Cursor ());
+    RegisterContextLLDB *register_ctx;
+
+    // Frame zero is a little different
+    if (m_frames.size() == 0)
+        return false;
+
+    uint32_t cur_idx = m_frames.size ();
+    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;
+        if (log)
+        {
+            log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk", 
+                        cur_idx < 100 ? cur_idx : 100, "", cur_idx);
         }
-        if (!first_register_ctx->GetCFA (first_cursor_sp->cfa))
+        return false;
+    }
+    if (!register_ctx->GetCFA (cursor_sp->cfa))
+    {
+        delete register_ctx;
+        if (log)
         {
-            delete first_register_ctx;
-            return 0;
+            log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
+                        cur_idx < 100 ? cur_idx : 100, "", cur_idx);
         }
-        if (!first_register_ctx->GetPC (first_cursor_sp->start_pc))
+        return false;
+    }
+    if (cursor_sp->cfa == (addr_t) -1 || cursor_sp->cfa == 1 || cursor_sp->cfa == 0)
+    {
+        delete register_ctx;
+        if (log)
         {
-            delete first_register_ctx;
-            return 0;
+            log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
+                        cur_idx < 100 ? cur_idx : 100, "", cur_idx);
         }
-        // Reuse the StackFrame provided by the processor native machine context for the first frame
-        first_register_ctx->SetStackFrame (m_thread.GetStackFrameAtIndex(0).get());
-        RegisterContextSP first_register_ctx_sp(first_register_ctx);
-        first_cursor_sp->reg_ctx = first_register_ctx_sp;
-        m_frames.push_back (first_cursor_sp);
-
-        // Now walk up the rest of the stack
-        while (1)
+        return false;
+    }
+    if (!register_ctx->GetPC (cursor_sp->start_pc))
+    {
+        delete register_ctx;
+        if (log)
         {
-            CursorSP cursor_sp(new Cursor ());
-            RegisterContextLLDB *register_ctx;
-            uint32_t cur_idx = m_frames.size ();
-            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;
-                if (log)
-                {
-                    log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk", 
-                                cur_idx < 100 ? cur_idx : 100, "", cur_idx);
-                }
-                break;
-            }
-            if (!register_ctx->GetCFA (cursor_sp->cfa))
-            {
-                delete register_ctx;
-                if (log)
-                {
-                    log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
-                                cur_idx < 100 ? cur_idx : 100, "", cur_idx);
-                }
-                break;
-            }
-            if (cursor_sp->cfa == (addr_t) -1 || cursor_sp->cfa == 1 || cursor_sp->cfa == 0)
-            {
-                delete register_ctx;
-                if (log)
-                {
-                    log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
-                                cur_idx < 100 ? cur_idx : 100, "", cur_idx);
-                }
-                break;
-            }
-            if (!register_ctx->GetPC (cursor_sp->start_pc))
-            {
-                delete register_ctx;
-                if (log)
-                {
-                    log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
-                                cur_idx < 100 ? cur_idx : 100, "", cur_idx);
-                }
-                break;
-            }
-            RegisterContextSP register_ctx_sp(register_ctx);
-            StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, register_ctx_sp, cursor_sp->cfa, cursor_sp->start_pc, &(cursor_sp->sctx));
-            register_ctx->SetStackFrame (frame);
-            cursor_sp->reg_ctx = register_ctx_sp;
-            m_frames.push_back (cursor_sp);
+            log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
+                        cur_idx < 100 ? cur_idx : 100, "", cur_idx);
         }
+        return false;
     }
-    return m_frames.size ();
+    RegisterContextSP register_ctx_sp(register_ctx);
+    StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, register_ctx_sp, cursor_sp->cfa, cursor_sp->start_pc, &(cursor_sp->sctx));
+    register_ctx->SetStackFrame (frame);
+    cursor_sp->reg_ctx = register_ctx_sp;
+    m_frames.push_back (cursor_sp);
+    return true;
 }
 
 bool
 UnwindLLDB::GetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
 {
-    // FIXME don't get the entire stack if it isn't needed.
     if (m_frames.size() == 0)
-        GetFrameCount();
+    {
+        if (!AddFirstFrame())
+            return false;
+    }
+
+    while (idx >= m_frames.size() && AddOneMoreFrame ())
+        ;
 
     if (idx < m_frames.size ())
     {
@@ -136,15 +159,21 @@
 UnwindLLDB::CreateRegisterContextForFrame (StackFrame *frame)
 {
     uint32_t idx = frame->GetFrameIndex ();
-    
-    // FIXME don't get the entire stack if it isn't needed.
-    if (m_frames.size() == 0)
-        GetFrameCount();
-    
+
     if (idx == 0)
     {
         return m_thread.GetRegisterContext();
     }
+
+    if (m_frames.size() == 0)
+    {
+        if (!AddFirstFrame())
+            return NULL;
+    }
+
+    while (idx >= m_frames.size() && AddOneMoreFrame ())
+        ;
+
     if (idx < m_frames.size ())
         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=118477&r1=118476&r2=118477&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h Mon Nov  8 20:31:21 2010
@@ -63,6 +63,9 @@
     typedef lldb::SharedPtr<Cursor>::Type CursorSP;
     std::vector<CursorSP> m_frames;
 
+    bool AddOneMoreFrame ();
+    bool AddFirstFrame ();
+
     //------------------------------------------------------------------
     // For UnwindLLDB only
     //------------------------------------------------------------------





More information about the lldb-commits mailing list