[Lldb-commits] [lldb] 65f2a75 - [lldb] [Process/FreeBSD] Report fork/vfork events to LLGS

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Sun Apr 25 10:41:21 PDT 2021


Author: Michał Górny
Date: 2021-04-25T19:40:46+02:00
New Revision: 65f2a757371e687cee6c36788fde1dab22895df7

URL: https://github.com/llvm/llvm-project/commit/65f2a757371e687cee6c36788fde1dab22895df7
DIFF: https://github.com/llvm/llvm-project/commit/65f2a757371e687cee6c36788fde1dab22895df7.diff

LOG: [lldb] [Process/FreeBSD] Report fork/vfork events to LLGS

Differential Revision: https://reviews.llvm.org/D100547

Added: 
    

Modified: 
    lldb/packages/Python/lldbsuite/test/dotest.py
    lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
    lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
    lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
    lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h

Removed: 
    


################################################################################
diff  --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index b3a6fb318d969..d48c578d7d75d 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -863,7 +863,7 @@ def checkForkVForkSupport():
     from lldbsuite.test import lldbplatformutil
 
     platform = lldbplatformutil.getPlatform()
-    if platform not in ["linux"]:
+    if platform not in ["freebsd", "linux"]:
         configuration.skip_categories.append("fork")
 
 

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
index 67a7b737c7d6c..6d9a7d7f0d9c1 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
@@ -128,13 +128,19 @@ NativeProcessFreeBSD::Factory::Attach(
   return std::move(process_up);
 }
 
+NativeProcessFreeBSD::Extension
+NativeProcessFreeBSD::Factory::GetSupportedExtensions() const {
+  return Extension::multiprocess | Extension::fork | Extension::vfork;
+}
+
 // Public Instance Methods
 
 NativeProcessFreeBSD::NativeProcessFreeBSD(::pid_t pid, int terminal_fd,
                                            NativeDelegate &delegate,
                                            const ArchSpec &arch,
                                            MainLoop &mainloop)
-    : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
+    : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
+      m_main_loop(mainloop) {
   if (m_terminal_fd != -1) {
     Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
     assert(status.Success());
@@ -247,19 +253,6 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
     return;
   }
 
-  if (info.pl_flags & PL_FLAG_FORKED) {
-    MonitorClone(info.pl_child_pid);
-    return;
-  }
-
-  if (info.pl_flags & PL_FLAG_VFORK_DONE) {
-    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))
@@ -271,6 +264,26 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
                info.pl_lwpid);
   }
 
+  if (info.pl_flags & PL_FLAG_FORKED) {
+    assert(thread);
+    MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread);
+    return;
+  }
+
+  if (info.pl_flags & PL_FLAG_VFORK_DONE) {
+    assert(thread);
+    if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) {
+      thread->SetStoppedByVForkDone();
+      SetState(StateType::eStateStopped, true);
+    } else {
+      Status error =
+          PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
+      if (error.Fail())
+        SetState(StateType::eStateInvalid);
+    }
+    return;
+  }
+
   if (info.pl_flags & PL_FLAG_SI) {
     assert(info.pl_siginfo.si_signo == SIGTRAP);
     LLDB_LOG(log, "SIGTRAP siginfo: si_code = {0}, pid = {1}",
@@ -933,7 +946,8 @@ bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const {
   return !m_arch.IsMIPS();
 }
 
-void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid) {
+void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
+                                        NativeThreadFreeBSD &parent_thread) {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
   LLDB_LOG(log, "fork, child_pid={0}", child_pid);
 
@@ -955,16 +969,42 @@ void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid) {
     return;
   }
 
-  MainLoop unused_loop;
-  NativeProcessFreeBSD child_process{static_cast<::pid_t>(child_pid),
-                                     m_terminal_fd, m_delegate, m_arch,
-                                     unused_loop};
-  child_process.Detach();
-  Status pt_error =
-      PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0);
-  if (pt_error.Fail()) {
-    LLDB_LOG_ERROR(log, pt_error.ToError(),
-                   "unable to resume parent process {1}: {0}", GetID());
-    SetState(StateType::eStateInvalid);
+  struct ptrace_lwpinfo info;
+  const auto siginfo_err = PtraceWrapper(PT_LWPINFO, child_pid, &info, sizeof(info));
+  if (siginfo_err.Fail()) {
+    LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
+    return;
+  }
+  assert(info.pl_event == PL_EVENT_SIGNAL);
+  lldb::tid_t child_tid = info.pl_lwpid;
+
+  std::unique_ptr<NativeProcessFreeBSD> child_process{
+      new NativeProcessFreeBSD(static_cast<::pid_t>(child_pid), m_terminal_fd,
+                               m_delegate, m_arch, m_main_loop)};
+  if (!is_vfork)
+    child_process->m_software_breakpoints = m_software_breakpoints;
+
+  Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+  if ((m_enabled_extensions & expected_ext) == expected_ext) {
+    child_process->SetupTrace();
+    for (const auto &thread : child_process->m_threads)
+      static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
+    child_process->SetState(StateType::eStateStopped, false);
+
+    m_delegate.NewSubprocess(this, std::move(child_process));
+    if (is_vfork)
+      parent_thread.SetStoppedByVFork(child_pid, child_tid);
+    else
+      parent_thread.SetStoppedByFork(child_pid, child_tid);
+    SetState(StateType::eStateStopped, true);
+  } else {
+    child_process->Detach();
+    Status pt_error =
+        PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0);
+    if (pt_error.Fail()) {
+      LLDB_LOG_ERROR(log, pt_error.ToError(),
+                     "unable to resume parent process {1}: {0}", GetID());
+      SetState(StateType::eStateInvalid);
+    }
   }
 }

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
index 3ed5f743deba2..7ec9d17d4cf48 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
@@ -39,6 +39,8 @@ class NativeProcessFreeBSD : public NativeProcessELF,
     llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
     Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
            MainLoop &mainloop) const override;
+
+    Extension GetSupportedExtensions() const override;
   };
 
   // NativeProcessProtocol Interface
@@ -96,6 +98,7 @@ class NativeProcessFreeBSD : public NativeProcessELF,
 private:
   MainLoop::SignalHandleUP m_sigchld_handle;
   ArchSpec m_arch;
+  MainLoop& m_main_loop;
   LazyBool m_supports_mem_region = eLazyBoolCalculate;
   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
 
@@ -113,7 +116,8 @@ class NativeProcessFreeBSD : public NativeProcessELF,
   void MonitorSIGSTOP(lldb::pid_t pid);
   void MonitorSIGTRAP(lldb::pid_t pid);
   void MonitorSignal(lldb::pid_t pid, int signal);
-  void MonitorClone(::pid_t child_pid);
+  void MonitorClone(::pid_t child_pid, bool is_vfork,
+                    NativeThreadFreeBSD &parent_thread);
 
   Status PopulateMemoryRegionCache();
   void SigchldHandler();

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
index 63be12fc7b2b0..80b3527aebced 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
@@ -130,6 +130,30 @@ void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
   m_stop_info.details.signal.signo = SIGTRAP;
 }
 
+void NativeThreadFreeBSD::SetStoppedByFork(lldb::pid_t child_pid,
+                                           lldb::tid_t child_tid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadFreeBSD::SetStoppedByVFork(lldb::pid_t child_pid,
+                                            lldb::tid_t child_tid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadFreeBSD::SetStoppedByVForkDone() {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVForkDone;
+}
+
 void NativeThreadFreeBSD::SetStoppedWithNoReason() {
   SetStopped();
 

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
index 249d2486b4f73..3ec6daa409e44 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
@@ -59,6 +59,9 @@ class NativeThreadFreeBSD : public NativeThreadProtocol {
   void SetStoppedByTrace();
   void SetStoppedByExec();
   void SetStoppedByWatchpoint(uint32_t wp_index);
+  void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+  void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+  void SetStoppedByVForkDone();
   void SetStoppedWithNoReason();
   void SetStopped();
   void SetRunning();


        


More information about the lldb-commits mailing list