summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target')
-rw-r--r--lldb/source/Target/Thread.cpp104
-rw-r--r--lldb/source/Target/ThreadList.cpp21
-rw-r--r--lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp28
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)
OpenPOWER on IntegriCloud