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(*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(*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(*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(1), signal); } Status NativeProcessNetBSD::Halt() { 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 +#include +// clang-format on + #include 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));