summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r--lldb/source/Target/Process.cpp54
1 files changed, 44 insertions, 10 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 6ad0ed05c6e..e46b548db11 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -36,6 +36,7 @@
#include "lldb/Target/TargetList.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanBase.h"
using namespace lldb;
using namespace lldb_private;
@@ -3102,8 +3103,17 @@ Process::StartPrivateStateThread (bool force)
snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state-override(pid=%llu)>", GetID());
else
snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state(pid=%llu)>", GetID());
+
+ // Create the private state thread, and start it running.
m_private_state_thread = Host::ThreadCreate (thread_name, Process::PrivateStateThread, this, NULL);
- return IS_VALID_LLDB_HOST_THREAD(m_private_state_thread);
+ bool success = IS_VALID_LLDB_HOST_THREAD(m_private_state_thread);
+ if (success)
+ {
+ ResumePrivateStateThread();
+ return true;
+ }
+ else
+ return false;
}
void
@@ -3247,8 +3257,8 @@ Process::PrivateStateThread (void *arg)
void *
Process::RunPrivateStateThread ()
{
- bool control_only = false;
- m_private_state_control_wait.SetValue (false, eBroadcastNever);
+ bool control_only = true;
+ m_private_state_control_wait.SetValue (true, eBroadcastNever);
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
@@ -3910,15 +3920,35 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
}
lldb::thread_t backup_private_state_thread = LLDB_INVALID_HOST_THREAD;
+ lldb::StateType old_state;
+ lldb::ThreadPlanSP stopper_base_plan_sp;
+ lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
if (Host::GetCurrentThread() == m_private_state_thread)
{
- // Yikes, we are running on the private state thread! So we can't call DoRunThreadPlan on this thread, since
- // then nobody will be around to fetch internal events.
+ // Yikes, we are running on the private state thread! So we can't wait for public events on this thread, since
+ // we are the thread that is generating public events.
// The simplest thing to do is to spin up a temporary thread to handle private state thread events while
- // we are doing the RunThreadPlan here.
+ // we are fielding public events here.
+ if (log)
+ log->Printf ("Running thread plan on private state thread, spinning up another state thread to handle the events.");
+
+
backup_private_state_thread = m_private_state_thread;
- printf ("Running thread plan on private state thread, spinning up another state thread to handle the events.\n");
+
+ // One other bit of business: we want to run just this thread plan and anything it pushes, and then stop,
+ // returning control here.
+ // But in the normal course of things, the plan above us on the stack would be given a shot at the stop
+ // event before deciding to stop, and we don't want that. So we insert a "stopper" base plan on the stack
+ // before the plan we want to run. Since base plans always stop and return control to the user, that will
+ // do just what we want.
+ stopper_base_plan_sp.reset(new ThreadPlanBase (*thread));
+ thread->QueueThreadPlan (stopper_base_plan_sp, false);
+ // Have to make sure our public state is stopped, since otherwise the reporting logic below doesn't work correctly.
+ old_state = m_public_state.GetValue();
+ m_public_state.SetValueNoLock(eStateStopped);
+
+ // Now spin up the private state thread:
StartPrivateStateThread(true);
}
@@ -3931,7 +3961,6 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
ProcessEventHijacker run_thread_plan_hijacker (*this, &listener);
- lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
if (log)
{
StreamString s;
@@ -3975,7 +4004,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
timeout_ptr = &real_timeout;
got_event = listener.WaitForEvent(timeout_ptr, event_sp);
- if (!got_event)
+ if (!got_event)
{
if (log)
log->PutCString("Didn't get any event after initial resume, exiting.");
@@ -4284,8 +4313,13 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
{
StopPrivateStateThread();
Error error;
- // Host::ThreadJoin(m_private_state_thread, &thread_result, &error);
m_private_state_thread = backup_private_state_thread;
+ if (stopper_base_plan_sp != NULL)
+ {
+ thread->DiscardThreadPlansUpToPlan(stopper_base_plan_sp);
+ }
+ m_public_state.SetValueNoLock(old_state);
+
}
OpenPOWER on IntegriCloud