mgorny created this revision.
mgorny added reviewers: krytarowski, labath.
Herald added subscribers: teemperor, abidh.
Herald added a project: LLDB.
Implement the full logic providing the ability to run, single-step
or suspend each thread separately. This replaces the old code that
propagated the status of first thread to all of them. It uses newer
APIs PT_RESUME/PT_SUSPEND and PT_SETSTEP/PT_CLEARSTEP.
It also uses the PT_SET_SIGINFO call to allow sending signal to a single
thread, in addition to sending it to entire process. Due to API
limitations, sending signal to 1<x<n threads is not supported, neither
is sending two different signals simultaneously.
Repository:
rLLDB LLDB
https://reviews.llvm.org/D64647
Files:
lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
Index: lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+++ lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
@@ -48,6 +48,10 @@
private:
// Interface for friend classes
+ Status Resume();
+ Status SingleStep();
+ Status Suspend();
+
void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
void SetStoppedByBreakpoint();
void SetStoppedByTrace();
Index: lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -17,6 +17,11 @@
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/State.h"
+// clang-format off
+#include <sys/types.h>
+#include <sys/ptrace.h>
+// clang-format on
+
#include <sstream>
using namespace lldb;
@@ -30,6 +35,38 @@
NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(process.GetArchitecture(), *this)
), m_stop_description() {}
+Status NativeThreadNetBSD::Resume() {
+ Status ret = NativeProcessNetBSD::PtraceWrapper(PT_RESUME, m_process.GetID(),
+ nullptr, GetID());
+ if (!ret.Success())
+ return ret;
+ ret = NativeProcessNetBSD::PtraceWrapper(PT_CLEARSTEP, m_process.GetID(),
+ nullptr, GetID());
+ if (ret.Success())
+ SetRunning();
+ return ret;
+}
+
+Status NativeThreadNetBSD::SingleStep() {
+ Status ret = NativeProcessNetBSD::PtraceWrapper(PT_RESUME, m_process.GetID(),
+ nullptr, GetID());
+ if (!ret.Success())
+ return ret;
+ ret = NativeProcessNetBSD::PtraceWrapper(PT_SETSTEP, m_process.GetID(),
+ nullptr, -GetID());
+ if (ret.Success())
+ SetStepping();
+ return ret;
+}
+
+Status NativeThreadNetBSD::Suspend() {
+ Status ret = NativeProcessNetBSD::PtraceWrapper(PT_SUSPEND, m_process.GetID(),
+ nullptr, GetID());
+ if (ret.Success())
+ SetStopped();
+ return ret;
+}
+
void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo,
const siginfo_t *info) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
Index: lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -328,53 +328,84 @@
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
LLDB_LOG(log, "pid {0}", GetID());
- const auto &thread = m_threads[0];
- const ResumeAction *const action =
- resume_actions.GetActionForThread(thread->GetID(), true);
+ Status ret;
+ int signal = LLDB_INVALID_SIGNAL_NUMBER;
+ int signaled_lwp;
+ size_t signaled_threads = 0;
+
+ for (const auto &abs_thread : m_threads) {
+ assert(abs_thread && "thread list should not contain NULL threads");
+ NativeThreadNetBSD& thread = static_cast<NativeThreadNetBSD &>(*abs_thread);
+
+ const ResumeAction *const action =
+ resume_actions.GetActionForThread(thread.GetID(), true);
+
+ if (action == nullptr) {
+ LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
+ thread.GetID());
+ continue;
+ }
- if (action == nullptr) {
- LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
- thread->GetID());
- return Status();
- }
+ LLDB_LOG(log, "processing resume action state {0} for pid {1} tid {2}",
+ action->state, GetID(), thread.GetID());
- Status error;
+ if (action->signal != LLDB_INVALID_SIGNAL_NUMBER) {
+ if (signal != LLDB_INVALID_SIGNAL_NUMBER && signal != action->signal)
+ return Status("NetBSD does not support passing multiple signals simultaneously");
- switch (action->state) {
- case eStateRunning: {
- // Run the thread, possibly feeding it the signal.
- error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1,
- action->signal);
- if (!error.Success())
- return error;
- for (const auto &thread : m_threads)
- static_cast<NativeThreadNetBSD &>(*thread).SetRunning();
- SetState(eStateRunning, true);
- break;
- }
- case eStateStepping:
- // Run the thread, possibly feeding it the signal.
- error = NativeProcessNetBSD::PtraceWrapper(PT_STEP, GetID(), (void *)1,
- action->signal);
- if (!error.Success())
- return error;
- for (const auto &thread : m_threads)
- static_cast<NativeThreadNetBSD &>(*thread).SetStepping();
- SetState(eStateStepping, true);
- break;
+ signal = action->signal;
+ signaled_lwp = thread.GetID();
+ signaled_threads++;
+ }
- case eStateSuspended:
- case eStateStopped:
- llvm_unreachable("Unexpected state");
+ switch (action->state) {
+ case eStateRunning:
+ ret = thread.Resume();
+ break;
+ case eStateStepping:
+ ret = thread.SingleStep();
+ break;
+ case eStateSuspended:
+ case eStateStopped:
+ if (action->signal != LLDB_INVALID_SIGNAL_NUMBER)
+ return Status("Passing signal to suspended thread unsupported");
- default:
- return Status("NativeProcessNetBSD::%s (): unexpected state %s specified "
- "for pid %" PRIu64 ", tid %" PRIu64,
- __FUNCTION__, StateAsCString(action->state), GetID(),
- thread->GetID());
+ ret = thread.Suspend();
+ break;
+
+ default:
+ return Status("NativeProcessNetBSD::%s (): unexpected state %s specified "
+ "for pid %" PRIu64 ", tid %" PRIu64,
+ __FUNCTION__, StateAsCString(action->state), GetID(),
+ thread.GetID());
+ }
+
+ if (ret.Success())
+ SetState(action->state, true);
+ else
+ return ret;
}
- return Status();
+ if (signal != LLDB_INVALID_SIGNAL_NUMBER) {
+ assert(signaled_threads > 0);
+
+ ptrace_siginfo_t siginfo;
+ siginfo.psi_siginfo.si_signo = signal;
+ siginfo.psi_siginfo.si_code = SI_NOINFO;
+ if (signaled_threads == m_threads.size()) // signal aimed at all threads
+ siginfo.psi_lwpid = 0;
+ else if (signaled_threads == 1)
+ siginfo.psi_lwpid = signaled_lwp;
+ else
+ return Status("NetBSD does not support passing signal to more than one thread simultaneously");
+
+ ret = PtraceWrapper(PT_SET_SIGINFO, GetID(), &siginfo, sizeof(siginfo));
+ if (!ret.Success())
+ return ret;
+ } else
+ signal = 0;
+
+ return PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void*>(1), signal);
}
Status NativeProcessNetBSD::Halt() {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits