[Lldb-commits] [lldb] c568985 - [lldb] [gdb-remote client] Remove breakpoints throughout vfork

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Wed Sep 1 01:33:55 PDT 2021


Author: Michał Górny
Date: 2021-09-01T10:33:48+02:00
New Revision: c568985845618eaef97a8a07ecc879e28cd70a94

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

LOG: [lldb] [gdb-remote client] Remove breakpoints throughout vfork

Temporarily remove breakpoints for the duration of vfork, in order
to prevent them from triggering in the child process.  Restore them
once the server reports that vfork has finished and it is ready to
resume execution.

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

Added: 
    lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test

Modified: 
    lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index f81e2acf3e17a..0ec972ec37d03 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -265,7 +265,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
       m_waiting_for_attach(false), m_destroy_tried_resuming(false),
       m_command_sp(), m_breakpoint_pc_offset(0),
       m_initial_tid(LLDB_INVALID_THREAD_ID), m_replay_mode(false),
-      m_allow_flash_writes(false), m_erased_flash_ranges() {
+      m_allow_flash_writes(false), m_erased_flash_ranges(),
+      m_vfork_in_progress(false) {
   m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
                                    "async thread should exit");
   m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
@@ -5492,7 +5493,7 @@ void ProcessGDBRemote::DidForkSwitchSoftwareBreakpoints(bool enable) {
          bp_site->GetType() == BreakpointSite::eExternal)) {
       m_gdb_comm.SendGDBStoppointTypePacket(
           eBreakpointSoftware, enable, bp_site->GetLoadAddress(),
-          bp_site->GetTrapOpcodeMaxByteSize(), GetInterruptTimeout());
+          GetSoftwareBreakpointTrapOpcode(bp_site), GetInterruptTimeout());
     }
   });
 }
@@ -5534,6 +5535,13 @@ void ProcessGDBRemote::DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
 void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
 
+  assert(!m_vfork_in_progress);
+  m_vfork_in_progress = true;
+
+  // Disable all software breakpoints for the duration of vfork.
+  if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
+    DidForkSwitchSoftwareBreakpoints(false);
+
   LLDB_LOG(log, "Detaching forked child {0}", child_pid);
   Status error = m_gdb_comm.Detach(false, child_pid);
   if (error.Fail()) {
@@ -5543,3 +5551,12 @@ void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
       return;
   }
 }
+
+void ProcessGDBRemote::DidVForkDone() {
+  assert(m_vfork_in_progress);
+  m_vfork_in_progress = false;
+
+  // Reenable all software breakpoints that were enabled before vfork.
+  if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
+    DidForkSwitchSoftwareBreakpoints(true);
+}

diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 70b3ca1ca3a22..ae5fce1c8370b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -232,6 +232,7 @@ class ProcessGDBRemote : public Process,
 
   void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override;
   void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override;
+  void DidVForkDone() override;
 
 protected:
   friend class ThreadGDBRemote;
@@ -296,6 +297,8 @@ class ProcessGDBRemote : public Process,
   using FlashRange = FlashRangeVector::Entry;
   FlashRangeVector m_erased_flash_ranges;
 
+  bool m_vfork_in_progress;
+
   // Accessors
   bool IsRunning(lldb::StateType state) {
     return state == lldb::eStateRunning || IsStepping(state);

diff  --git a/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test b/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test
new file mode 100644
index 0000000000000..f158d1a9c904e
--- /dev/null
+++ b/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test
@@ -0,0 +1,13 @@
+# REQUIRES: native
+# UNSUPPORTED: system-darwin
+# UNSUPPORTED: system-windows
+# RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_FORK=vfork -o %t
+# RUN: %lldb -b -s %s %t | FileCheck %s
+b parent_func
+b child_func
+process launch
+# CHECK-NOT: function run in parent
+# CHECK: stop reason = breakpoint
+continue
+# CHECK: function run in parent
+# CHECK: child exited: 0


        


More information about the lldb-commits mailing list