mgorny created this revision. mgorny added reviewers: krytarowski, labath, emaste. mgorny requested review of this revision.
Implement initial support for watching thread creation and termination. Update ptrace() calls to correctly indicate requested thread. Watchpoints are not supported yet. This patch fixes at least multithreaded register tests. https://reviews.llvm.org/D89413 Files: lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp
Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp +++ 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; Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp @@ -429,15 +429,15 @@ 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 +466,15 @@ 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); Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h +++ 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(); }; Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp +++ 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<NativeProcessFreeBSD &>(m_thread.GetProcess()); } Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h @@ -107,6 +107,7 @@ void SigchldHandler(); Status Attach(); + Status SetupTrace(); Status ReinitializeThreads(); }; Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp +++ 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,25 @@ 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<void*>(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<lldb::tid_t>(info.pl_lwpid)) { @@ -212,19 +227,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 +762,20 @@ 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();
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits