[Lldb-commits] [lldb] fd0af0c - [lldb] [Process/Linux] Report fork/vfork stop reason

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Sat Apr 24 02:26:40 PDT 2021


Author: Michał Górny
Date: 2021-04-24T11:08:34+02:00
New Revision: fd0af0cf08284de79fe1a5bcfdc2dad83794dcfe

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

LOG: [lldb] [Process/Linux] Report fork/vfork stop reason

Enable reporting fork/vfork events to the server when supported.
At this moment, this is used only to test the server code, as real
client does not report fork-events and vfork-events as supported.

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

Added: 
    

Modified: 
    lldb/packages/Python/lldbsuite/test/dotest.py
    lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
    lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
    lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
    lldb/source/Plugins/Process/Linux/NativeThreadLinux.h

Removed: 
    


################################################################################
diff  --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index 79f839f238114..b3a6fb318d969 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 []:
+    if platform not in ["linux"]:
         configuration.skip_categories.append("fork")
 
 

diff  --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 40ba5e2e604b2..86c5a093b6430 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -281,6 +281,11 @@ NativeProcessLinux::Factory::Attach(
       pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
 }
 
+NativeProcessLinux::Extension
+NativeProcessLinux::Factory::GetSupportedExtensions() const {
+  return Extension::multiprocess | Extension::fork | Extension::vfork;
+}
+
 // Public Instance Methods
 
 NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
@@ -288,7 +293,7 @@ NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
                                        const ArchSpec &arch, MainLoop &mainloop,
                                        llvm::ArrayRef<::pid_t> tids)
     : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
-      m_intel_pt_manager(pid) {
+      m_main_loop(mainloop), m_intel_pt_manager(pid) {
   if (m_terminal_fd != -1) {
     Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
     assert(status.Success());
@@ -647,7 +652,12 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
   }
 
   case (SIGTRAP | (PTRACE_EVENT_VFORK_DONE << 8)): {
-    ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+    if (bool(m_enabled_extensions & Extension::vfork)) {
+      thread.SetStoppedByVForkDone();
+      StopRunningThreads(thread.GetID());
+    }
+    else
+      ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
     break;
   }
 
@@ -912,16 +922,24 @@ bool NativeProcessLinux::MonitorClone(
     LLVM_FALLTHROUGH;
   case PTRACE_EVENT_FORK:
   case PTRACE_EVENT_VFORK: {
-    MainLoop unused_loop;
-    NativeProcessLinux child_process{static_cast<::pid_t>(child_pid),
-                                     m_terminal_fd,
-                                     m_delegate,
-                                     m_arch,
-                                     unused_loop,
-                                     {static_cast<::pid_t>(child_pid)}};
-    child_process.Detach();
-    ResumeThread(*parent_thread, parent_thread->GetState(),
-                 LLDB_INVALID_SIGNAL_NUMBER);
+    bool is_vfork = clone_info->event == PTRACE_EVENT_VFORK;
+    std::unique_ptr<NativeProcessLinux> child_process{new NativeProcessLinux(
+        static_cast<::pid_t>(child_pid), m_terminal_fd, m_delegate, m_arch,
+        m_main_loop, {static_cast<::pid_t>(child_pid)})};
+    if (!is_vfork)
+      child_process->m_software_breakpoints = m_software_breakpoints;
+
+    Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+    if (bool(m_enabled_extensions & expected_ext)) {
+      m_delegate.NewSubprocess(this, std::move(child_process));
+      // NB: non-vfork clone() is reported as fork
+      parent_thread->SetStoppedByFork(is_vfork, child_pid);
+      StopRunningThreads(parent_thread->GetID());
+    } else {
+      child_process->Detach();
+      ResumeThread(*parent_thread, parent_thread->GetState(),
+                   LLDB_INVALID_SIGNAL_NUMBER);
+    }
     break;
   }
   default:

diff  --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
index 86f6a1c27e5a4..64414e6920589 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -49,6 +49,8 @@ class NativeProcessLinux : 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
@@ -136,6 +138,7 @@ class NativeProcessLinux : 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;

diff  --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index fcc96e274d224..c44f10cc0a355 100644
--- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -394,6 +394,21 @@ void NativeThreadLinux::SetStoppedByTrace() {
   m_stop_info.details.signal.signo = SIGTRAP;
 }
 
+void NativeThreadLinux::SetStoppedByFork(bool is_vfork, lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason =
+      is_vfork ? StopReason::eStopReasonVFork : StopReason::eStopReasonFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_pid;
+}
+
+void NativeThreadLinux::SetStoppedByVForkDone() {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVForkDone;
+}
+
 void NativeThreadLinux::SetStoppedWithNoReason() {
   SetStopped();
 

diff  --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
index fe42270abed5c..f03de755c7bf3 100644
--- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -85,6 +85,10 @@ class NativeThreadLinux : public NativeThreadProtocol {
 
   void SetStoppedByTrace();
 
+  void SetStoppedByFork(bool is_vfork, lldb::pid_t child_pid);
+
+  void SetStoppedByVForkDone();
+
   void SetStoppedWithNoReason();
 
   void SetStoppedByProcessorTrace(llvm::StringRef description);


        


More information about the lldb-commits mailing list