[Lldb-commits] [PATCH] D100208: [lldb] [Process/Linux] Report fork/vfork stop reason to client

2021-04-13 Thread Michał Górny via Phabricator via lldb-commits
mgorny updated this revision to Diff 337238.
mgorny added a comment.

Rebase. Store `mainloop` arg of the original process, and pass it to the 
children to make them independent of the 'main' process.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100208/new/

https://reviews.llvm.org/D100208

Files:
  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

Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
===
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -85,6 +85,12 @@
 
   void SetStoppedByTrace();
 
+  void SetStoppedByFork(lldb::pid_t child_pid);
+
+  void SetStoppedByVFork(lldb::pid_t child_pid);
+
+  void SetStoppedByVForkDone();
+
   void SetStoppedWithNoReason();
 
   void SetStoppedByProcessorTrace(llvm::StringRef description);
Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
===
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -394,6 +394,28 @@
   m_stop_info.details.signal.signo = SIGTRAP;
 }
 
+void NativeThreadLinux::SetStoppedByFork(lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_pid;
+}
+
+void NativeThreadLinux::SetStoppedByVFork(lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVFork;
+  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();
 
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
===
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -49,6 +49,8 @@
 llvm::Expected>
 Attach(lldb::pid_t pid, NativeDelegate _delegate,
MainLoop ) const override;
+
+Extension GetSupportedExtensions() const override;
   };
 
   // NativeProcessProtocol Interface
@@ -136,6 +138,7 @@
 private:
   MainLoop::SignalHandleUP m_sigchld_handle;
   ArchSpec m_arch;
+  MainLoop& m_main_loop;
 
   LazyBool m_supports_mem_region = eLazyBoolCalculate;
   std::vector> m_mem_region_cache;
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -281,6 +281,11 @@
   pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
 }
 
+NativeProcessLinux::Extension
+NativeProcessLinux::Factory::GetSupportedExtensions() const {
+  return Extension::fork | Extension::vfork;
+}
+
 // Public Instance Methods
 
 NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
@@ -288,7 +293,7 @@
const ArchSpec , 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 @@
   }
 
   case (SIGTRAP | (PTRACE_EVENT_VFORK_DONE << 8)): {
-ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) {
+  thread.SetStoppedByVForkDone();
+  StopRunningThreads(thread.GetID());
+}
+else
+  ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
 break;
   }
 
@@ -912,16 +922,28 @@
 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;
+NativeProcessLinux *child_process = new 

[Lldb-commits] [PATCH] D100208: [lldb] [Process/Linux] Report fork/vfork stop reason to client

2021-04-11 Thread Michał Górny via Phabricator via lldb-commits
mgorny updated this revision to Diff 336670.
mgorny added a comment.

Report vfork-done stop to the client as well.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100208/new/

https://reviews.llvm.org/D100208

Files:
  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

Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
===
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -85,6 +85,12 @@
 
   void SetStoppedByTrace();
 
+  void SetStoppedByFork(lldb::pid_t child_pid);
+
+  void SetStoppedByVFork(lldb::pid_t child_pid);
+
+  void SetStoppedByVForkDone();
+
   void SetStoppedWithNoReason();
 
   void SetStoppedByProcessorTrace(llvm::StringRef description);
Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
===
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -394,6 +394,28 @@
   m_stop_info.details.signal.signo = SIGTRAP;
 }
 
+void NativeThreadLinux::SetStoppedByFork(lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_pid;
+}
+
+void NativeThreadLinux::SetStoppedByVFork(lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVFork;
+  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();
 
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
===
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -49,6 +49,8 @@
 llvm::Expected>
 Attach(lldb::pid_t pid, NativeDelegate _delegate,
MainLoop ) const override;
+
+Extension GetSupportedExtensions() const override;
   };
 
   // NativeProcessProtocol Interface
@@ -142,6 +144,9 @@
 
   lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
 
+  // Dummy loop for subprocess instances.
+  MainLoop m_subprocess_loop;
+
   /// Inferior memory (allocated by us) and its size.
   llvm::DenseMap m_allocated_memory;
 
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -281,6 +281,11 @@
   pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
 }
 
+NativeProcessLinux::Extension
+NativeProcessLinux::Factory::GetSupportedExtensions() const {
+  return Extension::fork | Extension::vfork;
+}
+
 // Public Instance Methods
 
 NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
@@ -647,7 +652,12 @@
   }
 
   case (SIGTRAP | (PTRACE_EVENT_VFORK_DONE << 8)): {
-ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) {
+  thread.SetStoppedByVForkDone();
+  StopRunningThreads(thread.GetID());
+}
+else
+  ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
 break;
   }
 
@@ -914,16 +924,29 @@
 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_delegates[0],
- 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;
+NativeProcessLinux *child_process = new NativeProcessLinux(
+static_cast<::pid_t>(child_pid), m_terminal_fd, *m_delegates[0], m_arch,
+m_subprocess_loop, {static_cast<::pid_t>(child_pid)});
+if (!is_vfork)
+  child_process->m_software_breakpoints = m_software_breakpoints;
+
+std::unique_ptr child_process_up{child_process};
+Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+if ((m_enabled_extensions & expected_ext) == expected_ext) {
+  for (auto  : 

[Lldb-commits] [PATCH] D100208: [lldb] [Process/Linux] Report fork/vfork stop reason to client

2021-04-11 Thread Michał Górny via Phabricator via lldb-commits
mgorny updated this revision to Diff 336657.
mgorny added a comment.

Copy software breakpoints to the forked process, to future-proof this patch for 
breakpoint support (I suppose there's no point in splitting it more).

Add `GetSupportedExtensions()` to actually enable the new code.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100208/new/

https://reviews.llvm.org/D100208

Files:
  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

Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
===
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -85,6 +85,10 @@
 
   void SetStoppedByTrace();
 
+  void SetStoppedByFork(lldb::pid_t child_pid);
+
+  void SetStoppedByVFork(lldb::pid_t child_pid);
+
   void SetStoppedWithNoReason();
 
   void SetStoppedByProcessorTrace(llvm::StringRef description);
Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
===
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -394,6 +394,22 @@
   m_stop_info.details.signal.signo = SIGTRAP;
 }
 
+void NativeThreadLinux::SetStoppedByFork(lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_pid;
+}
+
+void NativeThreadLinux::SetStoppedByVFork(lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_pid;
+}
+
 void NativeThreadLinux::SetStoppedWithNoReason() {
   SetStopped();
 
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
===
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -49,6 +49,8 @@
 llvm::Expected>
 Attach(lldb::pid_t pid, NativeDelegate _delegate,
MainLoop ) const override;
+
+Extension GetSupportedExtensions() const override;
   };
 
   // NativeProcessProtocol Interface
@@ -142,6 +144,9 @@
 
   lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
 
+  // Dummy loop for subprocess instances.
+  MainLoop m_subprocess_loop;
+
   /// Inferior memory (allocated by us) and its size.
   llvm::DenseMap m_allocated_memory;
 
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -281,6 +281,11 @@
   pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
 }
 
+NativeProcessLinux::Extension
+NativeProcessLinux::Factory::GetSupportedExtensions() const {
+  return Extension::fork | Extension::vfork;
+}
+
 // Public Instance Methods
 
 NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
@@ -914,16 +919,31 @@
 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_delegates[0],
- 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;
+NativeProcessLinux *child_process = new NativeProcessLinux(
+static_cast<::pid_t>(child_pid), m_terminal_fd, *m_delegates[0], m_arch,
+m_subprocess_loop, {static_cast<::pid_t>(child_pid)});
+if (!is_vfork)
+  child_process->m_software_breakpoints = m_software_breakpoints;
+
+std::unique_ptr child_process_up{child_process};
+Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+if ((m_enabled_extensions & expected_ext) == expected_ext) {
+  printf("DUPADUPA\n");
+  for (auto  : m_delegates)
+x->NewSubprocess(this, child_process_up);
+  // NB: non-vfork clone() is reported as fork
+  if (is_vfork)
+parent_thread->SetStoppedByVFork(child_pid);
+  else
+parent_thread->SetStoppedByFork(child_pid);
+  StopRunningThreads(parent_thread->GetID());
+} else {
+  printf("NODUPA\n");
+  child_process_up->Detach();
+  

[Lldb-commits] [PATCH] D100208: [lldb] [Process/Linux] Report fork/vfork stop reason to client

2021-04-09 Thread Michał Górny via Phabricator via lldb-commits
mgorny added a comment.

Ok, found the culprit. Now it's ready ;-).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100208/new/

https://reviews.llvm.org/D100208

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100208: [lldb] [Process/Linux] Report fork/vfork stop reason to client [WIP]

2021-04-09 Thread Michał Górny via Phabricator via lldb-commits
mgorny added a comment.

This is the final piece for moving minimal fork/vfork support to gdb-remote 
protocol. However, for some reason (unlike the original code in D99864 
), it crashes on random assertions about 
`m_enabled_extensions` value — probably memory corruption somewhere. I'm 
debugging it.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100208/new/

https://reviews.llvm.org/D100208

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100208: [lldb] [Process/Linux] Report fork/vfork stop reason to client [WIP]

2021-04-09 Thread Michał Górny via Phabricator via lldb-commits
mgorny created this revision.
mgorny added reviewers: labath, emaste, krytarowski.
mgorny requested review of this revision.

Enable reporting fork/vfork events to the client when supported.  This
switches from implicit server-side handling to client-controlled
gdb-remote protocol exchange.


https://reviews.llvm.org/D100208

Files:
  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


Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
===
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -85,6 +85,10 @@
 
   void SetStoppedByTrace();
 
+  void SetStoppedByFork(lldb::pid_t child_pid);
+
+  void SetStoppedByVFork(lldb::pid_t child_pid);
+
   void SetStoppedWithNoReason();
 
   void SetStoppedByProcessorTrace(llvm::StringRef description);
Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
===
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -394,6 +394,22 @@
   m_stop_info.details.signal.signo = SIGTRAP;
 }
 
+void NativeThreadLinux::SetStoppedByFork(lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_pid;
+}
+
+void NativeThreadLinux::SetStoppedByVFork(lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_pid;
+}
+
 void NativeThreadLinux::SetStoppedWithNoReason() {
   SetStopped();
 
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
===
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -142,6 +142,9 @@
 
   lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
 
+  // Dummy loop for subprocess instances.
+  MainLoop m_subprocess_loop;
+
   /// Inferior memory (allocated by us) and its size.
   llvm::DenseMap m_allocated_memory;
 
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -914,16 +914,26 @@
 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_delegates[0],
- m_arch,
- unused_loop,
- {static_cast<::pid_t>(child_pid)}};
-child_process.Detach();
-ResumeThread(*parent_thread, parent_thread->GetState(),
- LLDB_INVALID_SIGNAL_NUMBER);
+std::unique_ptr child_process{new 
NativeProcessLinux(
+static_cast<::pid_t>(child_pid), m_terminal_fd, *m_delegates[0], 
m_arch,
+m_subprocess_loop, {static_cast<::pid_t>(child_pid)})};
+Extension expected_ext = (clone_info->event != PTRACE_EVENT_VFORK)
+ ? Extension::fork
+ : Extension::vfork;
+if ((m_enabled_extensions & expected_ext) == expected_ext) {
+  for (auto  : m_delegates)
+x->NewSubprocess(this, child_process);
+  // NB: non-vfork clone() is reported as fork
+  if (clone_info->event != PTRACE_EVENT_VFORK)
+parent_thread->SetStoppedByFork(child_pid);
+  else
+parent_thread->SetStoppedByVFork(child_pid);
+  StopRunningThreads(parent_thread->GetID());
+} else {
+  child_process->Detach();
+  ResumeThread(*parent_thread, parent_thread->GetState(),
+   LLDB_INVALID_SIGNAL_NUMBER);
+}
 break;
   }
   default:


Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
===
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -85,6 +85,10 @@
 
   void SetStoppedByTrace();
 
+  void SetStoppedByFork(lldb::pid_t child_pid);
+
+  void SetStoppedByVFork(lldb::pid_t child_pid);
+
   void SetStoppedWithNoReason();
 
   void SetStoppedByProcessorTrace(llvm::StringRef description);
Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
===
---