summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Target/Thread.h4
-rw-r--r--lldb/source/Core/Debugger.cpp4
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp3
-rw-r--r--lldb/source/Plugins/Process/Utility/ThreadMemory.cpp3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp3
-rw-r--r--lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp3
-rw-r--r--lldb/source/Target/Process.cpp5
-rw-r--r--lldb/source/Target/Thread.cpp29
-rw-r--r--lldb/test/lang/cpp/dynamic-value/pass-to-base.cpp3
9 files changed, 48 insertions, 9 deletions
diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h
index 8ca07299f69..70f66c25c4d 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -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 ();
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 86b0cf53e3c..5941496336f 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -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)
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
index 567658d1983..3e42cf50d74 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
@@ -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
diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp
index 9e4c6d60733..cd3bd8c3105 100644
--- a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp
+++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp
@@ -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"
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index b63b42d1ab0..36fa418cf2b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -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"
diff --git a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp
index 001cda1b035..f88c4887aa9 100644
--- a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp
@@ -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.
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 077b9709924..3b37796f8d1 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -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,
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index 6e505f2119b..39157dd148f 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -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;
+}
diff --git a/lldb/test/lang/cpp/dynamic-value/pass-to-base.cpp b/lldb/test/lang/cpp/dynamic-value/pass-to-base.cpp
index a817bade941..2bccf330382 100644
--- a/lldb/test/lang/cpp/dynamic-value/pass-to-base.cpp
+++ b/lldb/test/lang/cpp/dynamic-value/pass-to-base.cpp
@@ -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
OpenPOWER on IntegriCloud