diff options
author | Greg Clayton <gclayton@apple.com> | 2013-05-09 01:55:29 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-05-09 01:55:29 +0000 |
commit | 6e0ff1a3cb5a1719c12ce156c4297d724c20b955 (patch) | |
tree | 2ea43845a7393dc9bb2df095f72b25a3393ca914 /lldb/source/Target | |
parent | 083fcdb41448362b803c47fe85dfeb830d25220c (diff) | |
download | bcm5719-llvm-6e0ff1a3cb5a1719c12ce156c4297d724c20b955.tar.gz bcm5719-llvm-6e0ff1a3cb5a1719c12ce156c4297d724c20b955.zip |
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).
llvm-svn: 181501
Diffstat (limited to 'lldb/source/Target')
-rw-r--r-- | lldb/source/Target/Thread.cpp | 104 | ||||
-rw-r--r-- | lldb/source/Target/ThreadList.cpp | 21 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp | 28 |
3 files changed, 106 insertions, 47 deletions
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 478021ac367..c4aa2544682 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -243,9 +243,9 @@ Thread::Thread (Process &process, lldb::tid_t tid) : 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 @@ Thread::Thread (Process &process, lldb::tid_t tid) : 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 @@ Thread::~Thread() 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 @@ Thread::GetStopInfo () } 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 @@ Thread::GetStopReason() 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 @@ Thread::SetShouldReportStop (Vote vote) 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 @@ Thread::SetStopInfoToNothing() bool Thread::ThreadStoppedForAReason (void) { - return (bool) GetPrivateStopReason (); + return (bool) GetPrivateStopInfo (); } bool @@ -554,18 +598,22 @@ Thread::ShouldResume (StateType resume_state) 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 @@ Thread::ShouldResume (StateType resume_state) if (need_to_resume && resume_state != eStateSuspended) { - m_actual_stop_info_sp.reset(); + m_stop_info_sp.reset(); } } @@ -676,7 +724,7 @@ Thread::ShouldStop (Event* event_ptr) // 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 @@ 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 (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) { diff --git a/lldb/source/Target/ThreadList.cpp b/lldb/source/Target/ThreadList.cpp index 8db2b40d292..1f8b351100a 100644 --- a/lldb/source/Target/ThreadList.cpp +++ b/lldb/source/Target/ThreadList.cpp @@ -505,6 +505,8 @@ ThreadList::WillResume () if ((*pos)->GetResumeState() != eStateSuspended && (*pos)->GetCurrentPlan()->StopOthers()) { + if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread()) + continue; wants_solo_run = true; break; } @@ -535,6 +537,8 @@ ThreadList::WillResume () if ((*pos)->GetResumeState() != eStateSuspended && (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers())) { + if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread()) + continue; (*pos)->SetupForResume (); } } @@ -546,7 +550,6 @@ ThreadList::WillResume () run_me_only_list.SetStopID(m_process->GetStopID()); - ThreadSP immediate_thread_sp; bool run_only_current_thread = false; for (pos = m_threads.begin(); pos != end; ++pos) @@ -555,6 +558,9 @@ ThreadList::WillResume () if (thread_sp->GetResumeState() != eStateSuspended && thread_sp->GetCurrentPlan()->StopOthers()) { + if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread()) + continue; + // You can't say "stop others" and also want yourself to be suspended. assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended); @@ -573,18 +579,7 @@ ThreadList::WillResume () bool need_to_resume = true; - if (immediate_thread_sp) - { - for (pos = m_threads.begin(); pos != end; ++pos) - { - ThreadSP thread_sp(*pos); - if (thread_sp.get() == immediate_thread_sp.get()) - thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()); - else - thread_sp->ShouldResume (eStateSuspended); - } - } - else if (run_me_only_list.GetSize (false) == 0) + if (run_me_only_list.GetSize (false) == 0) { // Everybody runs as they wish: for (pos = m_threads.begin(); pos != end; ++pos) diff --git a/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp b/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp index 00a19804b2c..ff4fee72a3a 100644 --- a/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ b/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp @@ -34,7 +34,8 @@ ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint (Thread &thread) : // first in the thread plan stack when stepping // over a breakpoint m_breakpoint_addr (LLDB_INVALID_ADDRESS), - m_auto_continue(false) + m_auto_continue(false), + m_reenabled_breakpoint_site (false) { m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC(); @@ -105,9 +106,7 @@ ThreadPlanStepOverBreakpoint::DoWillResume (StateType resume_state, bool current bool ThreadPlanStepOverBreakpoint::WillStop () { - BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr)); - if (bp_site_sp) - m_thread.GetProcess()->EnableBreakpointSite (bp_site_sp.get()); + ReenableBreakpointSite (); return true; } @@ -128,13 +127,30 @@ ThreadPlanStepOverBreakpoint::MischiefManaged () if (log) log->Printf("Completed step over breakpoint plan."); // Otherwise, re-enable the breakpoint we were stepping over, and we're done. + ReenableBreakpointSite (); + ThreadPlan::MischiefManaged (); + return true; + } +} + +void +ThreadPlanStepOverBreakpoint::ReenableBreakpointSite () +{ + if (!m_reenabled_breakpoint_site) + { + m_reenabled_breakpoint_site = true; BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr)); if (bp_site_sp) + { m_thread.GetProcess()->EnableBreakpointSite (bp_site_sp.get()); - ThreadPlan::MischiefManaged (); - return true; + } } } +void +ThreadPlanStepOverBreakpoint::ThreadDestroyed () +{ + ReenableBreakpointSite (); +} void ThreadPlanStepOverBreakpoint::SetAutoContinue (bool do_it) |