Patch from Matt Kopec <matt.kopec@intel.com> to fix the problem that if two breakpoin...
authorJim Ingham <jingham@apple.com>
Tue, 16 Oct 2012 00:09:33 +0000 (00:09 +0000)
committerJim Ingham <jingham@apple.com>
Tue, 16 Oct 2012 00:09:33 +0000 (00:09 +0000)
first breakpoint would skip the second.

llvm-svn: 166000

lldb/include/lldb/Target/Thread.h
lldb/source/Core/Debugger.cpp
lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
lldb/source/Plugins/Process/Utility/ThreadMemory.cpp
lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp
lldb/source/Target/Process.cpp
lldb/source/Target/Thread.cpp
lldb/test/lang/cpp/dynamic-value/pass-to-base.cpp

index 8ca0729..70f66c2 100644 (file)
@@ -858,6 +858,10 @@ protected:
     virtual lldb_private::Unwind *
     GetUnwinder ();
 
+    // Check to see whether the thread is still at the last breakpoint hit that stopped it.
+    virtual const bool
+    IsStillAtLastBreakpointHit();
+
     lldb::StackFrameListSP
     GetStackFrameList ();
     
index 86b0cf5..5941496 100644 (file)
@@ -1952,7 +1952,7 @@ Debugger::FormatPrompt
                                         else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
                                         {
                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
-                                            if (stop_info_sp)
+                                            if (stop_info_sp && stop_info_sp->IsValid())
                                             {
                                                 cstr = stop_info_sp->GetDescription();
                                                 if (cstr && cstr[0])
@@ -1965,7 +1965,7 @@ Debugger::FormatPrompt
                                         else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
                                         {
                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
-                                            if (stop_info_sp)
+                                            if (stop_info_sp && stop_info_sp->IsValid())
                                             {
                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
                                                 if (return_valobj_sp)
index 567658d..3e42cf5 100644 (file)
@@ -179,6 +179,9 @@ ThreadKDP::GetPrivateStopReason ()
         if (m_thread_stop_reason_stop_id != process_stop_id ||
             (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
         {
+            if (IsStillAtLastBreakpointHit())
+                return m_actual_stop_info_sp;
+
             if (m_cached_stop_info_sp)
                 SetStopInfo (m_cached_stop_info_sp);
             else
index 9e4c6d6..cd3bd8c 100644 (file)
@@ -107,6 +107,9 @@ ThreadMemory::GetPrivateStopReason ()
         if (m_thread_stop_reason_stop_id != process_stop_id ||
             (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
         {
+            if (IsStillAtLastBreakpointHit())
+                return m_actual_stop_info_sp;
+
             // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
             // for this thread, then m_actual_stop_info_sp will not ever contain
             // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
index b63b42d..36fa418 100644 (file)
@@ -225,6 +225,9 @@ ThreadGDBRemote::GetPrivateStopReason ()
         if (m_thread_stop_reason_stop_id != process_stop_id ||
             (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
         {
+            if (IsStillAtLastBreakpointHit())
+                return m_actual_stop_info_sp;
+
             // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
             // for this thread, then m_actual_stop_info_sp will not ever contain
             // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
index 001cda1..f88c488 100644 (file)
@@ -136,6 +136,9 @@ ThreadMachCore::GetPrivateStopReason ()
         if (m_thread_stop_reason_stop_id != process_stop_id ||
             (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
         {
+            if (IsStillAtLastBreakpointHit())
+                return m_actual_stop_info_sp;
+
             // TODO: can we query the initial state of the thread here?
             // For now I am just going to pretend that a SIGSTOP happened.
 
index 077b970..3b37796 100644 (file)
@@ -3741,7 +3741,7 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
             }
             
             StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
-            if (stop_info_sp)
+            if (stop_info_sp && stop_info_sp->IsValid())
             {
                 stop_info_sp->PerformAction(event_ptr);
                 // The stop action might restart the target.  If it does, then we want to mark that in the
@@ -4905,7 +4905,8 @@ Process::GetThreadStatus (Stream &strm,
         {
             if (only_threads_with_stop_reason)
             {
-                if (thread->GetStopInfo().get() == NULL)
+                StopInfoSP stop_info_sp = thread->GetStopInfo();
+                if (stop_info_sp.get() == NULL || !stop_info_sp->IsValid())
                     continue;
             }
             thread->GetStatus (strm, 
index 6e505f2..39157dd 100644 (file)
@@ -440,9 +440,11 @@ Thread::SetupForResume ()
         // telling the current plan it will resume, since we might change what the current
         // plan is.
 
-        lldb::addr_t pc = GetRegisterContext()->GetPC();
-        BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-        if (bp_site_sp && bp_site_sp->IsEnabled())
+        StopReason stop_reason = lldb::eStopReasonInvalid;
+        StopInfoSP stop_info_sp = GetStopInfo();
+        if (stop_info_sp.get())
+            stop_reason = stop_info_sp->GetStopReason();
+        if (stop_reason == lldb::eStopReasonBreakpoint)
         {
             // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
             // special to step over a breakpoint.
@@ -506,7 +508,7 @@ Thread::WillResume (StateType resume_state)
     // If the WillResume for the plan says we are faking a resume, then it will have set an appropriate stop info.
     // In that case, don't reset it here.
     
-    if (need_to_resume)
+    if (need_to_resume && resume_state != eStateSuspended)
     {
         m_actual_stop_info_sp.reset();
     }
@@ -1713,3 +1715,22 @@ Thread::Flush ()
     ClearStackFrames ();
     m_reg_context_sp.reset();
 }
+
+const bool
+Thread::IsStillAtLastBreakpointHit ()
+{
+    // If we are currently stopped at a breakpoint, always return that stopinfo and don't reset it.
+    // This allows threads to maintain their breakpoint stopinfo, such as when thread-stepping in
+    // multithreaded programs.
+    if (m_actual_stop_info_sp) {
+        StopReason stop_reason = m_actual_stop_info_sp->GetStopReason();
+        if (stop_reason == lldb::eStopReasonBreakpoint) {
+            uint64_t value = m_actual_stop_info_sp->GetValue();
+            lldb::addr_t pc = GetRegisterContext()->GetPC();
+            BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+            if (bp_site_sp && value == bp_site_sp->GetID())
+                return true;
+        }
+    }
+    return false;
+}
index a817bad..2bccf33 100644 (file)
@@ -23,7 +23,8 @@ public:
   doSomething (A &anotherA)
   {
     printf ("In A %p doing something with %d.\n", this, m_a_value);
-    printf ("Also have another A at %p: %d.\n", &anotherA, anotherA.Value()); // Break here in doSomething.
+    int tmp_value = anotherA.Value();
+    printf ("Also have another A at %p: %d.\n", &anotherA, tmp_value); // Break here in doSomething.
   }
 
   int