summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
diff options
context:
space:
mode:
authorChaoren Lin <chaorenl@google.com>2015-02-03 01:51:00 +0000
committerChaoren Lin <chaorenl@google.com>2015-02-03 01:51:00 +0000
commite9547b80522c32a95ec7fc57392a8db6f7770081 (patch)
tree7262afc04401be2c221bd5ad97e3ae7030c77cff /lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
parentaab58633b719c23760c39320e4792f96568fef58 (diff)
downloadbcm5719-llvm-e9547b80522c32a95ec7fc57392a8db6f7770081.tar.gz
bcm5719-llvm-e9547b80522c32a95ec7fc57392a8db6f7770081.zip
Fix up NativeProcessLinux::Interrupt() to use thread state coordinator mechanism.
llvm-svn: 227917
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 7b3d72c2c74..2a1690eae8f 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -2840,6 +2840,79 @@ NativeProcessLinux::Signal (int signo)
}
Error
+NativeProcessLinux::Interrupt ()
+{
+ // Pick a running thread (or if none, a not-dead stopped thread) as
+ // the chosen thread that will be the stop-reason thread.
+ Error error;
+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+
+ NativeThreadProtocolSP running_thread_sp;
+ NativeThreadProtocolSP stopped_thread_sp;
+ {
+ Mutex::Locker locker (m_threads_mutex);
+
+ if (log)
+ log->Printf ("NativeProcessLinux::%s selecting running thread for interrupt target", __FUNCTION__);
+
+ for (auto thread_sp : m_threads)
+ {
+ // The thread shouldn't be null but lets just cover that here.
+ if (!thread_sp)
+ continue;
+
+ // If we have a running or stepping thread, we'll call that the
+ // target of the interrupt.
+ const auto thread_state = thread_sp->GetState ();
+ if (thread_state == eStateRunning ||
+ thread_state == eStateStepping)
+ {
+ running_thread_sp = thread_sp;
+ break;
+ }
+ else if (!stopped_thread_sp && StateIsStoppedState (thread_state, true))
+ {
+ // Remember the first non-dead stopped thread. We'll use that as a backup if there are no running threads.
+ stopped_thread_sp = thread_sp;
+ }
+ }
+ }
+
+ if (!running_thread_sp && !stopped_thread_sp)
+ {
+ error.SetErrorString ("found no running/stepping or live stopped threads as target for interrupt");
+ if (log)
+ {
+ log->Printf ("NativeProcessLinux::%s skipping due to error: %s", __FUNCTION__, error.AsCString ());
+ }
+ return error;
+ }
+
+ NativeThreadProtocolSP deferred_signal_thread_sp = running_thread_sp ? running_thread_sp : stopped_thread_sp;
+
+ if (log)
+ log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " %s tid %" PRIu64 " chosen for interrupt target",
+ __FUNCTION__,
+ GetID (),
+ running_thread_sp ? "running" : "stopped",
+ deferred_signal_thread_sp->GetID ());
+
+ CallAfterRunningThreadsStop (deferred_signal_thread_sp->GetID (),
+ [=](lldb::tid_t deferred_notification_tid)
+ {
+ // Set the signal thread to the current thread.
+ SetCurrentThreadID (deferred_notification_tid);
+
+ // Set the thread state as stopped by the deferred signo.
+ reinterpret_cast<NativeThreadLinux*> (deferred_signal_thread_sp.get ())->SetStoppedBySignal (SIGSTOP);
+
+ // Tell the process delegate that the process is in a stopped state.
+ SetState (StateType::eStateStopped, true);
+ });
+ return error;
+}
+
+Error
NativeProcessLinux::Kill ()
{
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
OpenPOWER on IntegriCloud