diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h b/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h --- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h +++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h @@ -107,6 +107,7 @@ void SigchldHandler(); Status Attach(); + Status SetupTrace(); Status ReinitializeThreads(); }; diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp --- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp +++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp @@ -93,7 +93,7 @@ pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate, Info.GetArchitecture(), mainloop)); - status = process_up->ReinitializeThreads(); + status = process_up->SetupTrace(); if (status.Fail()) return status.ToError(); @@ -125,6 +125,10 @@ if (!status.Success()) return status.ToError(); + status = process_up->SetupTrace(); + if (status.Fail()) + return status.ToError(); + return std::move(process_up); } @@ -191,14 +195,26 @@ return; } assert(info.pl_event == PL_EVENT_SIGNAL); - // TODO: do we need to handle !PL_FLAG_SI? - assert(info.pl_flags & PL_FLAG_SI); - assert(info.pl_siginfo.si_signo == SIGTRAP); - - LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}, si_code = {2}", pid, - info.pl_lwpid, info.pl_siginfo.si_code); + LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}", pid, info.pl_lwpid); NativeThreadFreeBSD *thread = nullptr; + + if (info.pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) { + if (info.pl_flags & PL_FLAG_BORN) { + LLDB_LOG(log, "monitoring new thread, tid = {0}", info.pl_lwpid); + AddThread(info.pl_lwpid); + } else /*if (info.pl_flags & PL_FLAG_EXITED)*/ { + LLDB_LOG(log, "thread exited, tid = {0}", info.pl_lwpid); + RemoveThread(info.pl_lwpid); + } + + Status error = + PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast(1), 0); + if (error.Fail()) + SetState(StateType::eStateInvalid); + return; + } + if (info.pl_lwpid > 0) { for (const auto &t : m_threads) { if (t->GetID() == static_cast(info.pl_lwpid)) { @@ -212,19 +228,23 @@ info.pl_lwpid); } - switch (info.pl_siginfo.si_code) { - case TRAP_BRKPT: - if (thread) { - thread->SetStoppedByBreakpoint(); - FixupBreakpointPCAsNeeded(*thread); + if (info.pl_flags & PL_FLAG_SI) { + assert(info.pl_siginfo.si_signo == SIGTRAP); + + switch (info.pl_siginfo.si_code) { + case TRAP_BRKPT: + if (thread) { + thread->SetStoppedByBreakpoint(); + FixupBreakpointPCAsNeeded(*thread); + } + SetState(StateType::eStateStopped, true); + break; + case TRAP_TRACE: + if (thread) + thread->SetStoppedByTrace(); + SetState(StateType::eStateStopped, true); + break; } - SetState(StateType::eStateStopped, true); - break; - case TRAP_TRACE: - if (thread) - thread->SetStoppedByTrace(); - SetState(StateType::eStateStopped, true); - break; } } @@ -743,6 +763,21 @@ return buf; } +Status NativeProcessFreeBSD::SetupTrace() { + // Enable event reporting + int events; + Status status = + PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events)); + if (status.Fail()) + return status; + events |= PTRACE_LWP; + status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events)); + if (status.Fail()) + return status; + + return ReinitializeThreads(); +} + Status NativeProcessFreeBSD::ReinitializeThreads() { // Clear old threads m_threads.clear(); diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h --- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h +++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h @@ -37,7 +37,6 @@ virtual Status ClearWatchpointHit(uint32_t wp_index) = 0; protected: - Status DoRegisterSet(int req, void *buf); virtual NativeProcessFreeBSD &GetProcess(); virtual ::pid_t GetProcessPid(); }; diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp --- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp +++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp @@ -25,11 +25,6 @@ RegisterInfoInterface *reg_info_interface_p) : NativeRegisterContextRegisterInfo(native_thread, reg_info_interface_p) {} -Status NativeRegisterContextFreeBSD::DoRegisterSet(int ptrace_req, void *buf) { - return NativeProcessFreeBSD::PtraceWrapper(ptrace_req, GetProcessPid(), buf, - m_thread.GetID()); -} - NativeProcessFreeBSD &NativeRegisterContextFreeBSD::GetProcess() { return static_cast(m_thread.GetProcess()); } diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp --- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp @@ -429,15 +429,19 @@ Status NativeRegisterContextFreeBSD_x86_64::ReadRegisterSet(uint32_t set) { switch (set) { case GPRegSet: - return DoRegisterSet(PT_GETREGS, &m_gpr); + return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(), + &m_gpr); case FPRegSet: #if defined(__x86_64__) - return DoRegisterSet(PT_GETFPREGS, &m_fpr); + return NativeProcessFreeBSD::PtraceWrapper(PT_GETFPREGS, m_thread.GetID(), + &m_fpr); #else - return DoRegisterSet(PT_GETXMMREGS, &m_fpr); + return NativeProcessFreeBSD::PtraceWrapper(PT_GETXMMREGS, m_thread.GetID(), + &m_fpr); #endif case DBRegSet: - return DoRegisterSet(PT_GETDBREGS, &m_dbr); + return NativeProcessFreeBSD::PtraceWrapper(PT_GETDBREGS, m_thread.GetID(), + &m_dbr); case XSaveRegSet: { struct ptrace_xstate_info info; Status ret = NativeProcessFreeBSD::PtraceWrapper( @@ -466,15 +470,19 @@ Status NativeRegisterContextFreeBSD_x86_64::WriteRegisterSet(uint32_t set) { switch (set) { case GPRegSet: - return DoRegisterSet(PT_SETREGS, &m_gpr); + return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(), + &m_gpr); case FPRegSet: #if defined(__x86_64__) - return DoRegisterSet(PT_SETFPREGS, &m_fpr); + return NativeProcessFreeBSD::PtraceWrapper(PT_SETFPREGS, m_thread.GetID(), + &m_fpr); #else - return DoRegisterSet(PT_SETXMMREGS, &m_fpr); + return NativeProcessFreeBSD::PtraceWrapper(PT_SETXMMREGS, m_thread.GetID(), + &m_fpr); #endif case DBRegSet: - return DoRegisterSet(PT_SETDBREGS, &m_dbr); + return NativeProcessFreeBSD::PtraceWrapper(PT_SETDBREGS, m_thread.GetID(), + &m_dbr); case XSaveRegSet: // ReadRegisterSet() must always be called before WriteRegisterSet(). assert(m_xsave.size() > 0); diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp --- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp +++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp @@ -40,32 +40,27 @@ m_stop_description() {} Status NativeThreadFreeBSD::Resume() { - Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, m_process.GetID(), - nullptr, GetID()); + Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, GetID()); if (!ret.Success()) return ret; - ret = NativeProcessFreeBSD::PtraceWrapper(PT_CLEARSTEP, m_process.GetID(), - nullptr, GetID()); + ret = NativeProcessFreeBSD::PtraceWrapper(PT_CLEARSTEP, GetID()); if (ret.Success()) SetRunning(); return ret; } Status NativeThreadFreeBSD::SingleStep() { - Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, m_process.GetID(), - nullptr, GetID()); + Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, GetID()); if (!ret.Success()) return ret; - ret = NativeProcessFreeBSD::PtraceWrapper(PT_SETSTEP, m_process.GetID(), - nullptr, GetID()); + ret = NativeProcessFreeBSD::PtraceWrapper(PT_SETSTEP, GetID()); if (ret.Success()) SetStepping(); return ret; } Status NativeThreadFreeBSD::Suspend() { - Status ret = NativeProcessFreeBSD::PtraceWrapper( - PT_SUSPEND, m_process.GetID(), nullptr, GetID()); + Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_SUSPEND, GetID()); if (ret.Success()) SetStopped(); return ret;