summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Process.cpp
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2012-04-10 01:21:57 +0000
committerJim Ingham <jingham@apple.com>2012-04-10 01:21:57 +0000
commit076b3041c0706a957766f7e5e885f05b2eaf255e (patch)
treeb9ef0ad7e29855fdab17fd9c57b69dd98a3f9fb6 /lldb/source/Target/Process.cpp
parentd8ba464b6af29f66a7b045be57e4b30e47e573d2 (diff)
downloadbcm5719-llvm-076b3041c0706a957766f7e5e885f05b2eaf255e.tar.gz
bcm5719-llvm-076b3041c0706a957766f7e5e885f05b2eaf255e.zip
Two changes,
1) Start the PrivateStateThread stopped, and then in StartPrivateStateThread, make the private state thread and then resume it before we say the thread is created. That way we know it is listening for events by the time we get out of StartPrivateStateThread. 2) Backstop running a thread plan when calling Process::RunThreadPlan on the private state thread with a ThreadPlanBase so that running the plan doesn't pass its stop events to whatever plans happen to be above us on the thread plan stack. llvm-svn: 154368
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