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

Reply via email to