Fixed the StackFrame to correctly resolve the StackID's SymbolContextScope.

Added extra logging for stepping.

Fixed an issue where cached stack frame data could be lost between runs when
the thread plans read a stack frame.



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@112973 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h
index 9389032..ae31ced 100644
--- a/include/lldb/Target/StackFrame.h
+++ b/include/lldb/Target/StackFrame.h
@@ -153,6 +153,8 @@
     void
     UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame);
 
+    bool
+    HasCachedData () const;
 private:
     //------------------------------------------------------------------
     // For StackFrame only
diff --git a/include/lldb/Target/StackFrameList.h b/include/lldb/Target/StackFrameList.h
index 2822f95..888a959 100644
--- a/include/lldb/Target/StackFrameList.h
+++ b/include/lldb/Target/StackFrameList.h
@@ -28,13 +28,13 @@
     // Constructors and Destructors
     //------------------------------------------------------------------
     StackFrameList (Thread &thread, 
-                    StackFrameList *prev_frames, 
+                    const lldb::StackFrameListSP &prev_frames_sp,
                     bool show_inline_frames);
 
     ~StackFrameList();
 
     uint32_t
-    GetNumFrames();
+    GetNumFrames (bool can_create = true);
 
     lldb::StackFrameSP
     GetFrameAtIndex (uint32_t idx);
@@ -61,9 +61,15 @@
 
 protected:
 
+    friend class Thread;
+
     bool
     SetFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp);
 
+    static void
+    Merge (std::auto_ptr<StackFrameList>& curr_ap, 
+           lldb::StackFrameListSP& prev_sp);
+
     //------------------------------------------------------------------
     // Classes that inherit from StackFrameList can see and modify these
     //------------------------------------------------------------------
@@ -72,7 +78,7 @@
     typedef collection::const_iterator const_iterator;
 
     Thread &m_thread;
-    std::auto_ptr<StackFrameList> m_prev_frames_ap;
+    lldb::StackFrameListSP m_prev_frames_sp;
     mutable Mutex m_mutex;
     collection m_frames;
     uint32_t m_selected_frame_idx;
diff --git a/include/lldb/Target/StackID.h b/include/lldb/Target/StackID.h
index 9f4ef16..4baad51 100644
--- a/include/lldb/Target/StackID.h
+++ b/include/lldb/Target/StackID.h
@@ -51,12 +51,12 @@
     {
     }
 
-    const lldb::addr_t
+    lldb::addr_t
     GetPC() const
     {
         return m_pc;
     }
-
+    
     lldb::addr_t
     GetCallFrameAddress() const
     {
@@ -94,6 +94,16 @@
     }
 
 protected:
+
+    friend class StackFrame;
+    
+    void
+    SetPC (lldb::addr_t pc)
+    {
+        m_pc = pc;
+    }
+
+
     //------------------------------------------------------------------
     // Classes that inherit from StackID can see and modify these
     //------------------------------------------------------------------
diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h
index 5127392..6bd4ee6 100644
--- a/include/lldb/Target/Thread.h
+++ b/include/lldb/Target/Thread.h
@@ -556,7 +556,7 @@
     plan_stack          m_completed_plan_stack;  ///< Plans that have been completed by this stop.  They get deleted when the thread resumes.
     plan_stack          m_discarded_plan_stack;  ///< Plans that have been discarded by this stop.  They get deleted when the thread resumes.
     std::auto_ptr<StackFrameList> m_curr_frames_ap; ///< The stack frames that get lazily populated after a thread stops.
-    std::auto_ptr<StackFrameList> m_prev_frames_ap; ///< The previous stack frames from the last time this thread stopped.
+    lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from the last time this thread stopped.
     int                 m_resume_signal;    ///< The signal that should be used when continuing this thread.
     lldb::StateType     m_resume_state;     ///< The state that indicates what this thread should do when the process is resumed.
     std::auto_ptr<lldb_private::Unwind> m_unwinder_ap;
diff --git a/include/lldb/Target/ThreadList.h b/include/lldb/Target/ThreadList.h
index 8789ac2..b9bba99 100644
--- a/include/lldb/Target/ThreadList.h
+++ b/include/lldb/Target/ThreadList.h
@@ -99,6 +99,12 @@
     void
     SetStopID (uint32_t stop_id);
 
+    Mutex &
+    GetMutex ()
+    {
+        return m_threads_mutex;
+    }
+    
 protected:
 
     typedef std::vector<lldb::ThreadSP> collection;
diff --git a/include/lldb/lldb-private.h b/include/lldb/lldb-private.h
index a67ebf2..73f7da6 100644
--- a/include/lldb/lldb-private.h
+++ b/include/lldb/lldb-private.h
@@ -64,6 +64,10 @@
 const char *
 GetVersion ();
 
+const char *
+GetVoteAsCString (lldb::Vote vote);
+
+
 // The function below can be moved into lldb::Debugger when/if we get one
 ArchSpec &
 GetDefaultArchitecture ();
diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp
index 7297f1e..9609303 100644
--- a/source/Breakpoint/BreakpointLocation.cpp
+++ b/source/Breakpoint/BreakpointLocation.cpp
@@ -285,7 +285,7 @@
         if (level == lldb::eDescriptionLevelFull)
         {
             s->PutCString("where = ");
-            sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, true, true, false);
+            sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
         }
         else
         {
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index e8d596a..de94192 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -951,6 +951,7 @@
     if (log && log->GetMask().IsSet(GDBR_LOG_VERBOSE))
         log->Printf ("ProcessGDBRemote::%s (pid = %i)", __FUNCTION__, GetID());
 
+    Mutex::Locker locker (m_thread_list.GetMutex ());
     const uint32_t stop_id = GetStopID();
     if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID())
     {
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index b310f25..5237bbe 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -163,7 +163,7 @@
 
     if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
     {
-        if (m_id.GetSymbolContextScope () == NULL)
+        if (m_id.GetSymbolContextScope ())
         {
             m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
         }
@@ -624,7 +624,8 @@
 void
 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
 {
-    assert (GetStackID() == curr_frame.GetStackID());    // TODO: remove this after some testing
+    assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
+    m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
     assert (&m_thread == &curr_frame.m_thread);
     m_frame_index = curr_frame.m_frame_index;
     m_unwind_frame_index = curr_frame.m_unwind_frame_index;
@@ -642,3 +643,14 @@
 }
     
 
+bool
+StackFrame::HasCachedData () const
+{
+    if (m_variable_list_sp.get())
+        return true;
+    if (m_variable_list_value_objects.GetSize() > 0)
+        return true;
+    if (!m_disassembly.GetString().empty())
+        return true;
+    return false;
+}
\ No newline at end of file
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp
index 0b8b8bf..d2c9c59 100644
--- a/source/Target/StackFrameList.cpp
+++ b/source/Target/StackFrameList.cpp
@@ -30,9 +30,14 @@
 //----------------------------------------------------------------------
 // StackFrameList constructor
 //----------------------------------------------------------------------
-StackFrameList::StackFrameList(Thread &thread, StackFrameList *prev_frames, bool show_inline_frames) :
+StackFrameList::StackFrameList
+(
+    Thread &thread, 
+    const lldb::StackFrameListSP &prev_frames_sp, 
+    bool show_inline_frames
+) :
     m_thread (thread),
-    m_prev_frames_ap (prev_frames),
+    m_prev_frames_sp (prev_frames_sp),
     m_show_inlined_frames (show_inline_frames),
     m_mutex (Mutex::eMutexTypeRecursive),
     m_frames (),
@@ -49,11 +54,11 @@
 
 
 uint32_t
-StackFrameList::GetNumFrames()
+StackFrameList::GetNumFrames (bool can_create)
 {
     Mutex::Locker locker (m_mutex);
 
-    if (m_frames.size() <= 1)
+    if (can_create && m_frames.size() <= 1)
     {
         if (m_show_inlined_frames)
         {
@@ -165,9 +170,10 @@
                     }
                 }
             }
-            StackFrameList *prev_frames = m_prev_frames_ap.get();
-            if (prev_frames)
+
+            if (m_prev_frames_sp)
             {
+                StackFrameList *prev_frames = m_prev_frames_sp.get();
                 StackFrameList *curr_frames = this;
 
 #if defined (DEBUG_STACK_FRAMES)
@@ -189,17 +195,16 @@
                     StackFrameSP prev_frame_sp (prev_frames->m_frames[prev_frame_idx]);
 
 #if defined (DEBUG_STACK_FRAMES)
-                    s.Printf("\nCurrent frame #%u ", curr_frame_idx);
+                    s.Printf("\n\nCurr frame #%u ", curr_frame_idx);
                     if (curr_frame_sp)
-                        curr_frame_sp->Dump (&s, true);
+                        curr_frame_sp->Dump (&s, true, false);
                     else
                         s.PutCString("NULL");
-                    s.Printf("\nPrevious frame #%u ", prev_frame_idx);
+                    s.Printf("\nPrev frame #%u ", prev_frame_idx);
                     if (prev_frame_sp)
-                        prev_frame_sp->Dump (&s, true);
+                        prev_frame_sp->Dump (&s, true, false);
                     else
                         s.PutCString("NULL");
-                    s.EOL();
 #endif
 
                     StackFrame *curr_frame = curr_frame_sp.get();
@@ -223,8 +228,7 @@
 #endif
                 }
                 // We are done with the old stack frame list, we can release it now
-                m_prev_frames_ap.release();
-                prev_frames = NULL;
+                m_prev_frames_sp.reset();
             }
             
 #if defined (DEBUG_STACK_FRAMES)
@@ -332,7 +336,6 @@
     return frame_sp;
 }
 
-
 bool
 StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
 {
@@ -409,3 +412,104 @@
         }
     }
 }
+
+void
+StackFrameList::Merge (std::auto_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
+{
+    Mutex::Locker curr_locker (curr_ap.get() ? curr_ap->m_mutex.GetMutex() : NULL);
+    Mutex::Locker prev_locker (prev_sp.get() ? prev_sp->m_mutex.GetMutex() : NULL);
+
+#if defined (DEBUG_STACK_FRAMES)
+    StreamFile s(stdout);
+    s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n");
+    if (prev_sp.get())
+        prev_sp->Dump (&s);
+    else
+        s.PutCString ("NULL");
+    s.PutCString("\nCurr:\n");
+    if (curr_ap.get())
+        curr_ap->Dump (&s);
+    else
+        s.PutCString ("NULL");
+    s.EOL();
+#endif
+
+    if (curr_ap.get() == NULL || curr_ap->GetNumFrames (false) == 0)
+    {
+#if defined (DEBUG_STACK_FRAMES)
+        s.PutCString("No current frames, leave previous frames alone...\n");
+#endif
+        curr_ap.release();
+        return;
+    }
+
+    if (prev_sp.get() == NULL || prev_sp->GetNumFrames (false) == 0)
+    {
+#if defined (DEBUG_STACK_FRAMES)
+        s.PutCString("No previous frames, so use current frames...\n");
+#endif
+        // We either don't have any previous frames, or since we have more than
+        // one current frames it means we have all the frames and can safely
+        // replace our previous frames.
+        prev_sp.reset (curr_ap.release());
+        return;
+    }
+
+    const uint32_t num_curr_frames = curr_ap->GetNumFrames (false);
+    
+    if (num_curr_frames > 1)
+    {
+#if defined (DEBUG_STACK_FRAMES)
+        s.PutCString("We have more than one current frame, so use current frames...\n");
+#endif
+        // We have more than one current frames it means we have all the frames 
+        // and can safely replace our previous frames.
+        prev_sp.reset (curr_ap.release());
+
+#if defined (DEBUG_STACK_FRAMES)
+        s.PutCString("\nMerged:\n");
+        prev_sp->Dump (&s);
+#endif
+        return;
+    }
+
+    StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex (0));
+    StackFrameSP curr_frame_zero_sp(curr_ap->GetFrameAtIndex (0));
+    StackID curr_stack_id (curr_frame_zero_sp->GetStackID());
+    StackID prev_stack_id (prev_frame_zero_sp->GetStackID());
+
+    //const uint32_t num_prev_frames = prev_sp->GetNumFrames (false);
+
+#if defined (DEBUG_STACK_FRAMES)
+    s.Printf("\n%u previous frames with one current frame\n", num_prev_frames);
+#endif
+
+    // We have only a single current frame
+    // Our previous stack frames only had a single frame as well...
+    if (curr_stack_id == prev_stack_id)
+    {
+#if defined (DEBUG_STACK_FRAMES)
+        s.Printf("\nPrevious frame #0 is same as current frame #0, merge the cached data\n");
+#endif
+
+        curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame (*prev_frame_zero_sp);
+//        prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame (*curr_frame_zero_sp);
+//        prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp);
+    }
+    else if (curr_stack_id < prev_stack_id)
+    {
+#if defined (DEBUG_STACK_FRAMES)
+        s.Printf("\nCurrent frame #0 has a stack ID that is less than the previous frame #0, insert current frame zero in front of previous\n");
+#endif
+        prev_sp->m_frames.insert (prev_sp->m_frames.begin(), curr_frame_zero_sp);
+    }
+    
+    curr_ap.release();
+
+#if defined (DEBUG_STACK_FRAMES)
+    s.PutCString("\nMerged:\n");
+    prev_sp->Dump (&s);
+#endif
+
+
+}
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 1c8265a..ce9216a 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -293,17 +293,28 @@
 Thread::ShouldReportStop (Event* event_ptr)
 {
     StateType thread_state = GetResumeState ();
-    if (thread_state == eStateSuspended
-            || thread_state == eStateInvalid)
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+    if (thread_state == eStateSuspended || thread_state == eStateInvalid)
+    {
+        if (log)
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
         return eVoteNoOpinion;
+    }
 
     if (m_completed_plan_stack.size() > 0)
     {
         // Don't use GetCompletedPlan here, since that suppresses private plans.
+        if (log)
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote  for complete stack's back plan\n", GetID());
         return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
     }
     else
+    {
+        if (log)
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote  for current plan\n", GetID());
         return GetCurrentPlan()->ShouldReportStop (event_ptr);
+    }
 }
 
 Vote
@@ -797,7 +808,7 @@
 Thread::GetStackFrameList ()
 {
     if (m_curr_frames_ap.get() == NULL)
-        m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_ap.release(), true));
+        m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_sp, true));
     return *m_curr_frames_ap;
 }
 
@@ -813,8 +824,13 @@
 void
 Thread::ClearStackFrames ()
 {
-    if (m_curr_frames_ap.get())
-        m_prev_frames_ap = m_curr_frames_ap;
+    if (m_curr_frames_ap.get() && m_curr_frames_ap->GetNumFrames (false) > 1)
+        m_prev_frames_sp.reset (m_curr_frames_ap.release());
+    else
+        m_curr_frames_ap.release();
+
+//    StackFrameList::Merge (m_curr_frames_ap, m_prev_frames_sp);
+//    assert (m_curr_frames_ap.get() == NULL);
 }
 
 lldb::StackFrameSP
diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp
index 553641d..1c1cf3e 100644
--- a/source/Target/ThreadList.cpp
+++ b/source/Target/ThreadList.cpp
@@ -10,6 +10,8 @@
 
 #include <algorithm>
 
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/ThreadList.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/ThreadPlan.h"
@@ -177,24 +179,51 @@
 
     // Running events should never stop, obviously...
 
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
 
     bool should_stop = false;    
     m_process->UpdateThreadListIfNeeded();
 
     collection::iterator pos, end = m_threads.end();
 
+    if (log)
+        log->Printf ("%s %zu threads\n", __FUNCTION__, m_threads.size());
+
     // Run through the threads and ask whether we should stop.  Don't ask
     // suspended threads, however, it makes more sense for them to preserve their
     // state across the times the process runs but they don't get a chance to.
     for (pos = m_threads.begin(); pos != end; ++pos)
     {
         ThreadSP thread_sp(*pos);
-        if ((thread_sp->GetResumeState () != eStateSuspended) && (thread_sp->ThreadStoppedForAReason()))
+        
+        if (log)
+            log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx ", __FUNCTION__, thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC());
+
+        if (thread_sp->GetResumeState () == eStateSuspended)
         {
-            should_stop |=  thread_sp->ShouldStop(event_ptr);
+            if (log)
+                log->Printf("ignore: thread was suspended\n", thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC());
+            continue;
         }
+        
+        if (thread_sp->ThreadStoppedForAReason() == false)
+        {
+            if (log)
+                log->Printf("ignore: no stop reason\n", thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC());
+            continue;
+
+        }
+
+        const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
+        if (log)
+            log->Printf("should_stop = %i\n", thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC(), thread_should_stop);
+        if (thread_should_stop)
+            should_stop |= true;
     }
 
+    if (log)
+        log->Printf ("%s overall should_stop = %i\n", __FUNCTION__, should_stop);
+
     if (should_stop)
     {
         for (pos = m_threads.begin(); pos != end; ++pos)
@@ -210,10 +239,17 @@
 Vote
 ThreadList::ShouldReportStop (Event *event_ptr)
 {
+    Mutex::Locker locker(m_threads_mutex);
+
     Vote result = eVoteNoOpinion;
     m_process->UpdateThreadListIfNeeded();
     collection::iterator pos, end = m_threads.end();
 
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+    if (log)
+        log->Printf ("%s %zu threads\n", __FUNCTION__, m_threads.size());
+
     // Run through the threads and ask whether we should report this event.
     // For stopping, a YES vote wins over everything.  A NO vote wins over NO opinion.
     for (pos = m_threads.begin(); pos != end; ++pos)
@@ -221,26 +257,52 @@
         ThreadSP thread_sp(*pos);
         if (thread_sp->ThreadStoppedForAReason() && (thread_sp->GetResumeState () != eStateSuspended))
         {
-            switch (thread_sp->ShouldReportStop (event_ptr))
+            const lldb::Vote vote = thread_sp->ShouldReportStop (event_ptr);
+            if (log)
+                log->Printf  ("%s thread 0x%4.4x: pc = 0x%16.16llx vote: %s\n", 
+                              __FUNCTION__,
+                              thread_sp->GetID (), 
+                              thread_sp->GetRegisterContext()->GetPC(),
+                              GetVoteAsCString (vote));
+            switch (vote)
             {
-                case eVoteNoOpinion:
-                    continue;
-                case eVoteYes:
-                    result = eVoteYes;
-                    break;
-                case eVoteNo:
-                    if (result == eVoteNoOpinion)
-                        result = eVoteNo;
-                    break;
+            case eVoteNoOpinion:
+                continue;
+
+            case eVoteYes:
+                result = eVoteYes;
+                break;
+
+            case eVoteNo:
+                if (result == eVoteNoOpinion)
+                {
+                    result = eVoteNo;
+                }
+                else
+                {
+                    if (log)
+                        log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx voted %s, but lost out because result was %s\n", 
+                                     __FUNCTION__,
+                                     thread_sp->GetID (), 
+                                     thread_sp->GetRegisterContext()->GetPC(),
+                                     GetVoteAsCString (vote),
+                                     GetVoteAsCString (result));
+                }
+                break;
             }
         }
     }
+    if (log)
+        log->Printf ("%s returning %s\n", __FUNCTION__, GetVoteAsCString (result));
     return result;
 }
 
 Vote
 ThreadList::ShouldReportRun (Event *event_ptr)
 {
+
+    Mutex::Locker locker(m_threads_mutex);
+
     Vote result = eVoteNoOpinion;
     m_process->UpdateThreadListIfNeeded();
     collection::iterator pos, end = m_threads.end();
diff --git a/source/Target/ThreadPlan.cpp b/source/Target/ThreadPlan.cpp
index 6d3e99c..9675292 100644
--- a/source/Target/ThreadPlan.cpp
+++ b/source/Target/ThreadPlan.cpp
@@ -13,9 +13,10 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Target/Thread.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/State.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -88,12 +89,21 @@
 Vote
 ThreadPlan::ShouldReportStop (Event *event_ptr)
 {
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
     if (m_stop_vote == eVoteNoOpinion)
     {
         ThreadPlan *prev_plan = GetPreviousPlan ();
         if (prev_plan)
-            return prev_plan->ShouldReportStop (event_ptr);
+        {
+            Vote prev_vote = prev_plan->ShouldReportStop (event_ptr);
+            if (log)
+                log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote %s\n", GetVoteAsCString (prev_vote));
+            return prev_vote;
+        }
     }
+    if (log)
+        log->Printf ("ThreadPlan::ShouldReportStop() returning vote %s\n", GetVoteAsCString (m_stop_vote));
     return m_stop_vote;
 }
 
@@ -128,8 +138,21 @@
         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
 
         if (log)
-            log->Printf("Thread #%u: tid = 0x%4.4x about to resume the \"%s\" plan - state: %s - stop others: %d.", 
-                        m_thread.GetIndexID(), m_thread.GetID(),  m_name.c_str(), StateAsCString(resume_state), StopOthers());
+        {
+            RegisterContext *reg_ctx = m_thread.GetRegisterContext();
+            addr_t pc = reg_ctx->GetPC();
+            addr_t sp = reg_ctx->GetSP();
+            addr_t fp = reg_ctx->GetFP();
+            log->Printf("Thread #%u: tid = 0x%4.4x (pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx) about to resume the \"%s\" plan - state: %s - stop others: %d.", 
+                        m_thread.GetIndexID(), 
+                        m_thread.GetID(),  
+                        (uint64_t)pc,
+                        (uint64_t)sp,
+                        (uint64_t)fp,
+                        m_name.c_str(), 
+                        StateAsCString(resume_state), 
+                        StopOthers());
+        }
     }
     return true;
 }
diff --git a/source/Target/ThreadPlanStepRange.cpp b/source/Target/ThreadPlanStepRange.cpp
index 0885e95..dd21566 100644
--- a/source/Target/ThreadPlanStepRange.cpp
+++ b/source/Target/ThreadPlanStepRange.cpp
@@ -84,10 +84,12 @@
 Vote
 ThreadPlanStepRange::ShouldReportStop (Event *event_ptr)
 {
-    if (IsPlanComplete())
-        return eVoteYes;
-    else
-        return eVoteNo;
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+    const Vote vote = IsPlanComplete() ? eVoteYes : eVoteNo;
+    if (log)
+        log->Printf ("ThreadPlanStepRange::ShouldReportStop() returning vote %i\n", eVoteYes);
+    return vote;
 }
 
 bool
diff --git a/source/lldb.cpp b/source/lldb.cpp
index fc9d0e8..b6d5679 100644
--- a/source/lldb.cpp
+++ b/source/lldb.cpp
@@ -129,3 +129,14 @@
     static ArchSpec g_default_arch;
     return g_default_arch;
 }
+
+
+const char *
+lldb_private::GetVoteAsCString (lldb::Vote vote)
+{
+    static const char * g_vote_cstrings[] = { "no", "no opinion", "yes" };
+    if (vote >= eVoteNo && vote <= eVoteYes)
+        return g_vote_cstrings[vote-1];
+    return "invalid";
+}
+