Changed the formerly pure virtual function:
namespace lldb_private {
class Thread
{
virtual lldb::StopInfoSP
GetPrivateStopReason() = 0;
};
}
To not be virtual. The lldb_private::Thread now handles the correct caching and will call a new pure virtual function:
namespace lldb_private {
class Thread
{
virtual bool
CalculateStopInfo() = 0;
}
}
This function must be overridden by thead lldb_private::Thread subclass and the only thing it needs to do is to set the Thread::StopInfo() with the current stop reason and return true, or return false if there is no stop reason. The lldb_private::Thread class will take care of calling this function only when it is required. This allows lldb_private::Thread subclasses to be a bit simpler and not all need to duplicate the cache and invalidation settings.
Also renamed:
lldb::StopInfoSP
lldb_private::Thread::GetPrivateStopReason();
To:
lldb::StopInfoSP
lldb_private::Thread::GetPrivateStopInfo();
Also cleaned up a case where the ThreadPlanStepOverBreakpoint might not re-set its breakpoint if the thread disappears (which was happening due to a bug when using the OperatingSystem plug-ins with memory threads and real threads).
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@181501 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 478021a..c4aa254 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -243,9 +243,9 @@
UserID (tid),
Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()),
m_process_wp (process.shared_from_this()),
- m_actual_stop_info_sp (),
+ m_stop_info_sp (),
+ m_stop_info_stop_id (0),
m_index_id (process.GetNextThreadIndexID(tid)),
- m_protocol_tid (tid),
m_reg_context_sp (),
m_state (eStateUnloaded),
m_state_mutex (Mutex::eMutexTypeRecursive),
@@ -259,7 +259,6 @@
m_temporary_resume_state (eStateRunning),
m_unwinder_ap (),
m_destroy_called (false),
- m_thread_stop_reason_stop_id (0),
m_override_should_notify (eLazyBoolCalculate)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
@@ -283,11 +282,17 @@
void
Thread::DestroyThread ()
{
+ // Tell any plans on the plan stack that the thread is being destroyed since
+ // any active plans that have a thread go away in the middle of might need
+ // to do cleanup.
+ for (auto plan : m_plan_stack)
+ plan->ThreadDestroyed();
+
m_destroy_called = true;
m_plan_stack.clear();
m_discarded_plan_stack.clear();
m_completed_plan_stack.clear();
- m_actual_stop_info_sp.reset();
+ m_stop_info_sp.reset();
m_reg_context_sp.reset();
m_unwinder_ap.reset();
Mutex::Locker locker(m_frame_mutex);
@@ -366,19 +371,58 @@
}
else
{
- if ((m_thread_stop_reason_stop_id == stop_id) || // Stop info is valid, just return what we have (even if empty)
- (m_actual_stop_info_sp && m_actual_stop_info_sp->IsValid())) // Stop info is valid, just return what we have
+ if ((m_stop_info_stop_id == stop_id) || // Stop info is valid, just return what we have (even if empty)
+ (m_stop_info_sp && m_stop_info_sp->IsValid())) // Stop info is valid, just return what we have
{
- return m_actual_stop_info_sp;
+ return m_stop_info_sp;
}
else
{
- GetPrivateStopReason ();
- return m_actual_stop_info_sp;
+ GetPrivateStopInfo ();
+ return m_stop_info_sp;
}
}
}
+lldb::StopInfoSP
+Thread::GetPrivateStopInfo ()
+{
+ ProcessSP process_sp (GetProcess());
+ if (process_sp)
+ {
+ ProcessSP process_sp (GetProcess());
+ if (process_sp)
+ {
+ const uint32_t process_stop_id = process_sp->GetStopID();
+ if (m_stop_info_stop_id != process_stop_id)
+ {
+ if (m_stop_info_sp)
+ {
+ if (m_stop_info_sp->IsValid())
+ {
+ SetStopInfo (m_stop_info_sp);
+ }
+ else
+ {
+ if (IsStillAtLastBreakpointHit())
+ SetStopInfo(m_stop_info_sp);
+ else
+ m_stop_info_sp.reset();
+ }
+ }
+
+ if (!m_stop_info_sp)
+ {
+ if (CalculateStopInfo() == false)
+ SetStopInfo (StopInfoSP());
+ }
+ }
+ }
+ }
+ return m_stop_info_sp;
+}
+
+
lldb::StopReason
Thread::GetStopReason()
{
@@ -393,20 +437,20 @@
void
Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp)
{
- m_actual_stop_info_sp = stop_info_sp;
- if (m_actual_stop_info_sp)
+ m_stop_info_sp = stop_info_sp;
+ if (m_stop_info_sp)
{
- m_actual_stop_info_sp->MakeStopInfoValid();
+ m_stop_info_sp->MakeStopInfoValid();
// If we are overriding the ShouldReportStop, do that here:
if (m_override_should_notify != eLazyBoolCalculate)
- m_actual_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
+ m_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
}
ProcessSP process_sp (GetProcess());
if (process_sp)
- m_thread_stop_reason_stop_id = process_sp->GetStopID();
+ m_stop_info_stop_id = process_sp->GetStopID();
else
- m_thread_stop_reason_stop_id = UINT32_MAX;
+ m_stop_info_stop_id = UINT32_MAX;
}
void
@@ -417,8 +461,8 @@
else
{
m_override_should_notify = (vote == eVoteYes ? eLazyBoolYes : eLazyBoolNo);
- if (m_actual_stop_info_sp)
- m_actual_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
+ if (m_stop_info_sp)
+ m_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
}
}
@@ -433,7 +477,7 @@
bool
Thread::ThreadStoppedForAReason (void)
{
- return (bool) GetPrivateStopReason ();
+ return (bool) GetPrivateStopInfo ();
}
bool
@@ -554,18 +598,22 @@
m_temporary_resume_state = resume_state;
- // Make sure m_actual_stop_info_sp is valid
- GetPrivateStopReason();
+ lldb::ThreadSP backing_thread_sp (GetBackingThread ());
+ if (backing_thread_sp)
+ backing_thread_sp->m_temporary_resume_state = resume_state;
+
+ // Make sure m_stop_info_sp is valid
+ GetPrivateStopInfo();
// This is a little dubious, but we are trying to limit how often we actually fetch stop info from
// the target, 'cause that slows down single stepping. So assume that if we got to the point where
// we're about to resume, and we haven't yet had to fetch the stop reason, then it doesn't need to know
// about the fact that we are resuming...
const uint32_t process_stop_id = GetProcess()->GetStopID();
- if (m_thread_stop_reason_stop_id == process_stop_id &&
- (m_actual_stop_info_sp && m_actual_stop_info_sp->IsValid()))
+ if (m_stop_info_stop_id == process_stop_id &&
+ (m_stop_info_sp && m_stop_info_sp->IsValid()))
{
- StopInfo *stop_info = GetPrivateStopReason().get();
+ StopInfo *stop_info = GetPrivateStopInfo().get();
if (stop_info)
stop_info->WillResume (resume_state);
}
@@ -590,7 +638,7 @@
if (need_to_resume && resume_state != eStateSuspended)
{
- m_actual_stop_info_sp.reset();
+ m_stop_info_sp.reset();
}
}
@@ -676,7 +724,7 @@
// First query the stop info's ShouldStopSynchronous. This handles "synchronous" stop reasons, for example the breakpoint
// command on internal breakpoints. If a synchronous stop reason says we should not stop, then we don't have to
// do any more work on this stop.
- StopInfoSP private_stop_info (GetPrivateStopReason());
+ StopInfoSP private_stop_info (GetPrivateStopInfo());
if (private_stop_info && private_stop_info->ShouldStopSynchronous(event_ptr) == false)
{
if (log)
@@ -1906,10 +1954,10 @@
// 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 (m_stop_info_sp) {
+ StopReason stop_reason = m_stop_info_sp->GetStopReason();
if (stop_reason == lldb::eStopReasonBreakpoint) {
- uint64_t value = m_actual_stop_info_sp->GetValue();
+ uint64_t value = m_stop_info_sp->GetValue();
lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
if (reg_ctx_sp)
{