[Lldb-commits] [lldb] 121cff7 - Revert "[lldb] [Process] Watch for fork/vfork notifications" and associated followups

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 13 02:03:18 PDT 2021


Author: Pavel Labath
Date: 2021-04-13T11:03:06+02:00
New Revision: 121cff78a8032a73aa4fb820625dc1ecae8e3997

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

LOG: Revert "[lldb] [Process] Watch for fork/vfork notifications" and associated followups

This commit has caused the following tests to be flaky:
TestThreadSpecificBpPlusCondition.py
TestExitDuringExpression.py

The exact cause is not known yet, but since both tests deal with
threads, my guess is it has something to do with the tracking of
creation of new threads (which the commit touches upon).

This reverts the following commits:
d01bff8cbdc98fb8751f7bf10af19b47ae5c445d,
ba62ebc48e8c424ce3a78ba01acda679d536dd47,
e761b6b4c58d4f7ae1073d925d7cb321d68ee93a,
a345419ee03095c8cdfbe1c2728467c4da8fa0a4.

Added: 
    

Modified: 
    lldb/source/Host/linux/Host.cpp
    lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
    lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
    lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
    lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
    lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
    lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
    lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h
    lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
    lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
    lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
    lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
    lldb/test/API/functionalities/gdb_remote_client/TestMultiprocess.py

Removed: 
    lldb/include/lldb/Host/linux/Host.h
    lldb/test/Shell/Subprocess/Inputs/fork.cpp
    lldb/test/Shell/Subprocess/clone-follow-parent-wp.test
    lldb/test/Shell/Subprocess/clone-follow-parent.test
    lldb/test/Shell/Subprocess/fork-follow-parent-wp.test
    lldb/test/Shell/Subprocess/fork-follow-parent.test
    lldb/test/Shell/Subprocess/lit.local.cfg
    lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test
    lldb/test/Shell/Subprocess/vfork-follow-parent.test


################################################################################
diff  --git a/lldb/include/lldb/Host/linux/Host.h b/lldb/include/lldb/Host/linux/Host.h
deleted file mode 100644
index 409a9fc9b322..000000000000
--- a/lldb/include/lldb/Host/linux/Host.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//===-- Host.h --------------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_HOST_LINUX_HOST_H
-#define LLDB_HOST_LINUX_HOST_H
-
-#include "lldb/lldb-types.h"
-#include "llvm/ADT/Optional.h"
-
-namespace lldb_private {
-
-// Get PID (i.e. the primary thread ID) corresponding to the specified TID.
-llvm::Optional<lldb::pid_t> getPIDForTID(lldb::pid_t tid);
-
-} // namespace lldb_private
-
-#endif // #ifndef LLDB_HOST_LINUX_HOST_H

diff  --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp
index 334634a357f5..520a00df35f6 100644
--- a/lldb/source/Host/linux/Host.cpp
+++ b/lldb/source/Host/linux/Host.cpp
@@ -27,7 +27,6 @@
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
-#include "lldb/Host/linux/Host.h"
 #include "lldb/Host/linux/Support.h"
 #include "lldb/Utility/DataExtractor.h"
 
@@ -54,8 +53,7 @@ class ProcessLaunchInfo;
 }
 
 static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
-                          ProcessState &State, ::pid_t &TracerPid,
-                          ::pid_t &Tgid) {
+                          ProcessState &State, ::pid_t &TracerPid) {
   Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
 
   auto BufferOrError = getProcFile(Pid, "status");
@@ -109,9 +107,6 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
     } else if (Line.consume_front("TracerPid:")) {
       Line = Line.ltrim();
       Line.consumeInteger(10, TracerPid);
-    } else if (Line.consume_front("Tgid:")) {
-      Line = Line.ltrim();
-      Line.consumeInteger(10, Tgid);
     }
   }
   return true;
@@ -209,7 +204,6 @@ static void GetProcessEnviron(::pid_t pid, ProcessInstanceInfo &process_info) {
 static bool GetProcessAndStatInfo(::pid_t pid,
                                   ProcessInstanceInfo &process_info,
                                   ProcessState &State, ::pid_t &tracerpid) {
-  ::pid_t tgid;
   tracerpid = 0;
   process_info.Clear();
 
@@ -220,7 +214,7 @@ static bool GetProcessAndStatInfo(::pid_t pid,
   GetProcessEnviron(pid, process_info);
 
   // Get User and Group IDs and get tracer pid.
-  if (!GetStatusInfo(pid, process_info, State, tracerpid, tgid))
+  if (!GetStatusInfo(pid, process_info, State, tracerpid))
     return false;
 
   return true;
@@ -314,14 +308,3 @@ Environment Host::GetEnvironment() { return Environment(environ); }
 Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
   return Status("unimplemented");
 }
-
-llvm::Optional<lldb::pid_t> lldb_private::getPIDForTID(lldb::pid_t tid) {
-  ::pid_t tracerpid, tgid = LLDB_INVALID_PROCESS_ID;
-  ProcessInstanceInfo process_info;
-  ProcessState state;
-
-  if (!GetStatusInfo(tid, process_info, state, tracerpid, tgid) ||
-      tgid == LLDB_INVALID_PROCESS_ID)
-    return llvm::None;
-  return tgid;
-}

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
index 5e371672eaf2..5961ff4439db 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
@@ -247,19 +247,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))
@@ -718,17 +705,17 @@ NativeProcessFreeBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
 
 void NativeProcessFreeBSD::SigchldHandler() {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+  // Process all pending waitpid notifications.
   int status;
   ::pid_t wait_pid =
       llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG);
 
   if (wait_pid == 0)
-    return;
+    return; // We are done.
 
   if (wait_pid == -1) {
     Status error(errno, eErrorTypePOSIX);
     LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
-    return;
   }
 
   WaitStatus wait_status = WaitStatus::Decode(status);
@@ -898,7 +885,7 @@ Status NativeProcessFreeBSD::SetupTrace() {
       PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
   if (status.Fail())
     return status;
-  events |= PTRACE_LWP | PTRACE_FORK | PTRACE_VFORK;
+  events |= PTRACE_LWP;
   status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
   if (status.Fail())
     return status;
@@ -932,53 +919,3 @@ Status NativeProcessFreeBSD::ReinitializeThreads() {
 bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const {
   return !m_arch.IsMIPS();
 }
-
-void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  LLDB_LOG(log, "fork, child_pid={0}", child_pid);
-
-  int status;
-  ::pid_t wait_pid =
-      llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
-  if (wait_pid != child_pid) {
-    LLDB_LOG(log,
-             "waiting for pid {0} failed. Assuming the pid has "
-             "disappeared in the meantime",
-             child_pid);
-    return;
-  }
-  if (WIFEXITED(status)) {
-    LLDB_LOG(log,
-             "waiting for pid {0} returned an 'exited' event. Not "
-             "tracking it.",
-             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.ReinitializeThreads();
-  auto *child_thread =
-      static_cast<NativeThreadFreeBSD *>(child_process.GetCurrentThread());
-  assert(child_thread);
-  // new processes inherit dbregs, so we need to clear them
-  llvm::Error error = child_thread->GetRegisterContext().ClearDBRegs();
-  if (error) {
-    LLDB_LOG_ERROR(log, std::move(error),
-                   "failed to clear dbregs in forked process {1}: {0}",
-                   child_pid);
-    SetState(StateType::eStateInvalid);
-    return;
-  }
-
-  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 3ed5f743deba..ceffc370ca33 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
@@ -113,7 +113,6 @@ 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);
 
   Status PopulateMemoryRegionCache();
   void SigchldHandler();

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
index cf2afcfa98d4..0000484beac9 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
@@ -32,8 +32,6 @@ class NativeRegisterContextFreeBSD
   virtual llvm::Error
   CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) = 0;
 
-  virtual llvm::Error ClearDBRegs() { return llvm::Error::success(); }
-
 protected:
   virtual NativeProcessFreeBSD &GetProcess();
   virtual ::pid_t GetProcessPid();

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
index 74abf24a847c..e98e0a8a0caa 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
@@ -285,19 +285,4 @@ NativeRegisterContextFreeBSD_arm64::WriteHardwareDebugRegs(DREGType) {
 #endif
 }
 
-llvm::Error NativeRegisterContextFreeBSD_arm64::ClearDBRegs() {
-#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
-  if (llvm::Error error = ReadHardwareDebugInfo())
-    return error;
-
-  for (uint32_t i = 0; i < m_max_hbp_supported; i++)
-    m_hbp_regs[i].control = 0;
-  for (uint32_t i = 0; i < m_max_hwp_supported; i++)
-    m_hwp_regs[i].control = 0;
-  return WriteHardwareDebugRegs(eDREGTypeWATCH);
-#else
-  return llvm::error::success();
-#endif
-}
-
 #endif // defined (__aarch64__)

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
index ae6f5741639a..a230f8fed48a 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
@@ -58,8 +58,6 @@ class NativeRegisterContextFreeBSD_arm64
   llvm::Error
   CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
 
-  llvm::Error ClearDBRegs() override;
-
 private:
   // Due to alignment, FreeBSD reg/fpreg are a few bytes larger than
   // LLDB's GPR/FPU structs.  However, all fields have matching offsets

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
index 5415b49b32c9..9328d606ad26 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
@@ -653,10 +653,4 @@ NativeRegisterContextFreeBSD_x86_64::GetYMMSplitReg(uint32_t reg) {
   return YMMSplitPtr{&fpreg->sv_xmm[reg_index], &ymmreg[reg_index]};
 }
 
-llvm::Error NativeRegisterContextFreeBSD_x86_64::ClearDBRegs() {
-  uint64_t zero = 0;
-  RegisterValue dr7{zero};
-  return WriteRegister(GetDR(7), dr7).ToError();
-}
-
 #endif // defined(__x86_64__)

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h
index e4932c9afe49..efd0f91f77b9 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h
@@ -55,8 +55,6 @@ class NativeRegisterContextFreeBSD_x86_64
   llvm::Error
   CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
 
-  llvm::Error ClearDBRegs() override;
-
 private:
   // Private member types.
   enum RegSetKind {

diff  --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 4880d4dc5d81..5a876ce5befe 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -30,7 +30,6 @@
 #include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/common/NativeRegisterContext.h"
-#include "lldb/Host/linux/Host.h"
 #include "lldb/Host/linux/Ptrace.h"
 #include "lldb/Host/linux/Uio.h"
 #include "lldb/Host/posix/ProcessLauncherPosixFork.h"
@@ -384,22 +383,14 @@ Status NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) {
   ptrace_opts |= PTRACE_O_TRACEEXIT;
 
   // Have the tracer trace threads which spawn in the inferior process.
+  // TODO: if we want to support tracing the inferiors' child, add the
+  // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK)
   ptrace_opts |= PTRACE_O_TRACECLONE;
 
   // Have the tracer notify us before execve returns (needed to disable legacy
   // SIGTRAP generation)
   ptrace_opts |= PTRACE_O_TRACEEXEC;
 
-  // Have the tracer trace forked children.
-  ptrace_opts |= PTRACE_O_TRACEFORK;
-
-  // Have the tracer trace vforks.
-  ptrace_opts |= PTRACE_O_TRACEVFORK;
-
-  // Have the tracer trace vfork-done in order to restore breakpoints after
-  // the child finishes sharing memory.
-  ptrace_opts |= PTRACE_O_TRACEVFORKDONE;
-
   return PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void *)ptrace_opts);
 }
 
@@ -453,7 +444,8 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
     LLDB_LOG(log, "tid {0}, si_code: {1}, si_pid: {2}", pid, info.si_code,
              info.si_pid);
 
-    MonitorClone(pid, llvm::None);
+    NativeThreadLinux &thread = AddThread(pid, /*resume*/ true);
+    ThreadWasCreated(thread);
     return;
   }
 
@@ -517,24 +509,29 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
   }
 }
 
-void NativeProcessLinux::WaitForCloneNotification(::pid_t pid) {
+void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
 
-  // The PID is not tracked yet, let's wait for it to appear.
+  if (GetThreadByID(tid)) {
+    // We are already tracking the thread - we got the event on the new thread
+    // (see MonitorSignal) before this one. We are done.
+    return;
+  }
+
+  // The thread is not tracked yet, let's wait for it to appear.
   int status = -1;
   LLDB_LOG(log,
-           "received clone event for pid {0}. pid not tracked yet, "
-           "waiting for it to appear...",
-           pid);
-  ::pid_t wait_pid =
-      llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &status, __WALL);
-  // Since we are waiting on a specific pid, this must be the creation event.
+           "received thread creation event for tid {0}. tid not tracked "
+           "yet, waiting for thread to appear...",
+           tid);
+  ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, &status, __WALL);
+  // Since we are waiting on a specific tid, this must be the creation event.
   // But let's do some checks just in case.
-  if (wait_pid != pid) {
+  if (wait_pid != tid) {
     LLDB_LOG(log,
-             "waiting for pid {0} failed. Assuming the pid has "
+             "waiting for tid {0} failed. Assuming the thread has "
              "disappeared in the meantime",
-             pid);
+             tid);
     // The only way I know of this could happen is if the whole process was
     // SIGKILLed in the mean time. In any case, we can't do anything about that
     // now.
@@ -542,15 +539,17 @@ void NativeProcessLinux::WaitForCloneNotification(::pid_t pid) {
   }
   if (WIFEXITED(status)) {
     LLDB_LOG(log,
-             "waiting for pid {0} returned an 'exited' event. Not "
-             "tracking it.",
-             pid);
+             "waiting for tid {0} returned an 'exited' event. Not "
+             "tracking the thread.",
+             tid);
     // Also a very improbable event.
-    m_pending_pid_map.erase(pid);
     return;
   }
 
-  MonitorClone(pid, llvm::None);
+  LLDB_LOG(log, "pid = {0}: tracking new thread tid {1}", GetID(), tid);
+  NativeThreadLinux &new_thread = AddThread(tid, /*resume*/ true);
+
+  ThreadWasCreated(new_thread);
 }
 
 void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
@@ -561,26 +560,26 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
   assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
 
   switch (info.si_code) {
-  case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
-  case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+  // TODO: these two cases are required if we want to support tracing of the
+  // inferiors' children.  We'd need this to debug a monitor. case (SIGTRAP |
+  // (PTRACE_EVENT_FORK << 8)): case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+
   case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): {
-    // This can either mean a new thread or a new process spawned via
-    // clone(2) without SIGCHLD or CLONE_VFORK flag.  Note that clone(2)
-    // can also cause PTRACE_EVENT_FORK and PTRACE_EVENT_VFORK if one
-    // of these flags are passed.
+    // This is the notification on the parent thread which informs us of new
+    // thread creation. We don't want to do anything with the parent thread so
+    // we just resume it. In case we want to implement "break on thread
+    // creation" functionality, we would need to stop here.
 
     unsigned long event_message = 0;
     if (GetEventMessage(thread.GetID(), &event_message).Fail()) {
       LLDB_LOG(log,
-               "pid {0} received clone() event but GetEventMessage failed "
-               "so we don't know the new pid/tid",
+               "pid {0} received thread creation event but "
+               "GetEventMessage failed so we don't know the new tid",
                thread.GetID());
-      ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
-    } else {
-      if (!MonitorClone(event_message, {{(info.si_code >> 8), thread.GetID()}}))
-        WaitForCloneNotification(event_message);
-    }
+    } else
+      WaitForNewThread(event_message);
 
+    ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
     break;
   }
 
@@ -646,11 +645,6 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
     break;
   }
 
-  case (SIGTRAP | (PTRACE_EVENT_VFORK_DONE << 8)): {
-    ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
-    break;
-  }
-
   case 0:
   case TRAP_TRACE:  // We receive this on single stepping.
   case TRAP_HWBKPT: // We receive this on watchpoint hit
@@ -860,79 +854,6 @@ void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
   StopRunningThreads(thread.GetID());
 }
 
-bool NativeProcessLinux::MonitorClone(
-    lldb::pid_t child_pid,
-    llvm::Optional<NativeProcessLinux::CloneInfo> clone_info) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  LLDB_LOG(log, "clone, child_pid={0}, clone info?={1}", child_pid,
-           clone_info.hasValue());
-
-  auto find_it = m_pending_pid_map.find(child_pid);
-  if (find_it == m_pending_pid_map.end()) {
-    // not in the map, so this is the first signal for the PID
-    m_pending_pid_map.insert({child_pid, clone_info});
-    return false;
-  }
-  m_pending_pid_map.erase(find_it);
-
-  // second signal for the pid
-  assert(clone_info.hasValue() != find_it->second.hasValue());
-  if (!clone_info) {
-    // child signal does not indicate the event, so grab the one stored
-    // earlier
-    clone_info = find_it->second;
-  }
-
-  LLDB_LOG(log, "second signal for child_pid={0}, parent_tid={1}, event={2}",
-           child_pid, clone_info->parent_tid, clone_info->event);
-
-  auto *parent_thread = GetThreadByID(clone_info->parent_tid);
-  assert(parent_thread);
-
-  switch (clone_info->event) {
-  case PTRACE_EVENT_CLONE: {
-    // PTRACE_EVENT_CLONE can either mean a new thread or a new process.
-    // Try to grab the new process' PGID to figure out which one it is.
-    // If PGID is the same as the PID, then it's a new process.  Otherwise,
-    // it's a thread.
-    auto tgid_ret = getPIDForTID(child_pid);
-    if (tgid_ret != child_pid) {
-      // A new thread should have PGID matching our process' PID.
-      assert(!tgid_ret || tgid_ret.getValue() == GetID());
-
-      NativeThreadLinux &child_thread = AddThread(child_pid, /*resume*/ true);
-      // Resume the newly created thread.
-      ResumeThread(child_thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
-      ThreadWasCreated(child_thread);
-
-      // Resume the parent.
-      ResumeThread(*parent_thread, parent_thread->GetState(),
-                   LLDB_INVALID_SIGNAL_NUMBER);
-      break;
-    }
-  }
-    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);
-    break;
-  }
-  default:
-    llvm_unreachable("unknown clone_info.event");
-  }
-
-  return true;
-}
-
 bool NativeProcessLinux::SupportHardwareSingleStepping() const {
   if (m_arch.GetMachine() == llvm::Triple::arm || m_arch.IsMIPS())
     return false;

diff  --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
index 86f6a1c27e5a..77905a193c2b 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -157,7 +157,7 @@ class NativeProcessLinux : public NativeProcessELF,
 
   void MonitorCallback(lldb::pid_t pid, bool exited, WaitStatus status);
 
-  void WaitForCloneNotification(::pid_t pid);
+  void WaitForNewThread(::pid_t tid);
 
   void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
 
@@ -234,21 +234,6 @@ class NativeProcessLinux : public NativeProcessELF,
 
   /// Manages Intel PT process and thread traces.
   IntelPTManager m_intel_pt_manager;
-
-  struct CloneInfo {
-    int event;
-    lldb::tid_t parent_tid;
-  };
-
-  // Map of child processes that have been signaled once, and we are
-  // waiting for the second signal.
-  llvm::DenseMap<lldb::pid_t, llvm::Optional<CloneInfo>> m_pending_pid_map;
-
-  // Handle a clone()-like event.  If received by parent, clone_info contains
-  // additional info.  Returns true if the event is handled, or false if it
-  // is pending second notification.
-  bool MonitorClone(lldb::pid_t child_pid,
-                    llvm::Optional<CloneInfo> clone_info);
 };
 
 } // namespace process_linux

diff  --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 1f357e3e96d7..57f0eb3cceb6 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -256,24 +256,6 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
     SetState(StateType::eStateStopped, true);
     return;
   }
-  case TRAP_CHLD: {
-    ptrace_state_t pst;
-    Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst));
-    if (error.Fail()) {
-      SetState(StateType::eStateInvalid);
-      return;
-    }
-
-    if (pst.pe_report_event == PTRACE_VFORK_DONE) {
-      Status error =
-          PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
-      if (error.Fail())
-        SetState(StateType::eStateInvalid);
-      return;
-    } else
-      MonitorClone(pst.pe_other_pid);
-    return;
-  }
   case TRAP_LWP: {
     ptrace_state_t pst;
     Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst));
@@ -528,7 +510,7 @@ Status NativeProcessNetBSD::Detach() {
   if (GetID() == LLDB_INVALID_PROCESS_ID)
     return error;
 
-  return PtraceWrapper(PT_DETACH, GetID(), reinterpret_cast<void *>(1));
+  return PtraceWrapper(PT_DETACH, GetID());
 }
 
 Status NativeProcessNetBSD::Signal(int signo) {
@@ -756,17 +738,17 @@ Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
 
 void NativeProcessNetBSD::SigchldHandler() {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+  // Process all pending waitpid notifications.
   int status;
   ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status,
                                                  WALLSIG | WNOHANG);
 
   if (wait_pid == 0)
-    return;
+    return; // We are done.
 
   if (wait_pid == -1) {
     Status error(errno, eErrorTypePOSIX);
     LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
-    return;
   }
 
   WaitStatus wait_status = WaitStatus::Decode(status);
@@ -954,9 +936,8 @@ Status NativeProcessNetBSD::SetupTrace() {
       PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
   if (status.Fail())
     return status;
-  // TODO: PTRACE_POSIX_SPAWN?
-  events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT | PTRACE_FORK |
-                         PTRACE_VFORK | PTRACE_VFORK_DONE;
+  // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN?
+  events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
   status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
   if (status.Fail())
     return status;
@@ -993,39 +974,3 @@ Status NativeProcessNetBSD::ReinitializeThreads() {
 
   return error;
 }
-
-void NativeProcessNetBSD::MonitorClone(::pid_t child_pid) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  LLDB_LOG(log, "clone, child_pid={0}", child_pid);
-
-  int status;
-  ::pid_t wait_pid =
-      llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
-  if (wait_pid != child_pid) {
-    LLDB_LOG(log,
-             "waiting for pid {0} failed. Assuming the pid has "
-             "disappeared in the meantime",
-             child_pid);
-    return;
-  }
-  if (WIFEXITED(status)) {
-    LLDB_LOG(log,
-             "waiting for pid {0} returned an 'exited' event. Not "
-             "tracking it.",
-             child_pid);
-    return;
-  }
-
-  MainLoop unused_loop;
-  NativeProcessNetBSD 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, std::move(pt_error.ToError()),
-                   "unable to resume parent process {1}: {0}", GetID());
-    SetState(StateType::eStateInvalid);
-  }
-}

diff  --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 3384078a0d6d..3d59a4f72e94 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -106,7 +106,6 @@ class NativeProcessNetBSD : 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);
 
   Status PopulateMemoryRegionCache();
   void SigchldHandler();

diff  --git a/lldb/test/API/functionalities/gdb_remote_client/TestMultiprocess.py b/lldb/test/API/functionalities/gdb_remote_client/TestMultiprocess.py
index 551bf7234283..baf9f9cddedf 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestMultiprocess.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestMultiprocess.py
@@ -1,5 +1,6 @@
 from __future__ import print_function
 import lldb
+import unittest
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test.decorators import *
 from gdbclientutils import *

diff  --git a/lldb/test/Shell/Subprocess/Inputs/fork.cpp b/lldb/test/Shell/Subprocess/Inputs/fork.cpp
deleted file mode 100644
index 44242934bd3e..000000000000
--- a/lldb/test/Shell/Subprocess/Inputs/fork.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <assert.h>
-#if defined(TEST_CLONE)
-#include <sched.h>
-#endif
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-
-int g_val = 0;
-
-void parent_func() {
-  g_val = 1;
-  printf("function run in parent\n");
-}
-
-int child_func(void *unused) {
-  // we need to avoid memory modifications for vfork(), yet we want
-  // to be able to test watchpoints, so do the next best thing
-  // and restore the original value
-  g_val = 2;
-  g_val = 0;
-  return 0;
-}
-
-int main() {
-  alignas(uintmax_t) char stack[4096];
-
-#if defined(TEST_CLONE)
-  pid_t pid = clone(child_func, &stack[sizeof(stack)], 0, NULL);
-#elif defined(TEST_FORK)
-  pid_t pid = TEST_FORK();
-  if (pid == 0)
-    _exit(child_func(NULL));
-#endif
-  assert(pid != -1);
-
-  parent_func();
-  int status, wait_flags = 0;
-#if defined(TEST_CLONE)
-  wait_flags = __WALL;
-#endif
-  pid_t waited = waitpid(pid, &status, wait_flags);
-  assert(waited == pid);
-  assert(WIFEXITED(status));
-  printf("child exited: %d\n", WEXITSTATUS(status));
-
-  return 0;
-}

diff  --git a/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test b/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test
deleted file mode 100644
index 67d94af3ca10..000000000000
--- a/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test
+++ /dev/null
@@ -1,14 +0,0 @@
-# REQUIRES: native && (system-linux || system-netbsd) && dbregs-set
-# clone() tests fails on arm64 Linux, PR #49899
-# UNSUPPORTED: system-linux && target-aarch64
-# RUN: %clangxx_host -g %p/Inputs/fork.cpp -DTEST_CLONE -o %t
-# RUN: %lldb -b -s %s %t | FileCheck %s
-process launch -s
-watchpoint set variable -w write g_val
-# CHECK: Watchpoint created:
-continue
-# CHECK-NOT: function run in parent
-# CHECK: stop reason = watchpoint
-continue
-# CHECK: function run in parent
-# CHECK: child exited: 0

diff  --git a/lldb/test/Shell/Subprocess/clone-follow-parent.test b/lldb/test/Shell/Subprocess/clone-follow-parent.test
deleted file mode 100644
index 3d89279bbb29..000000000000
--- a/lldb/test/Shell/Subprocess/clone-follow-parent.test
+++ /dev/null
@@ -1,12 +0,0 @@
-# REQUIRES: native && (system-linux || system-netbsd)
-# clone() tests fails on arm64 Linux, PR #49899
-# UNSUPPORTED: system-linux && target-aarch64
-# RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_CLONE -o %t
-# RUN: %lldb -b -s %s %t | FileCheck %s
-b parent_func
-process launch
-# CHECK-NOT: function run in parent
-# CHECK: stop reason = breakpoint
-continue
-# CHECK: function run in parent
-# CHECK: child exited: 0

diff  --git a/lldb/test/Shell/Subprocess/fork-follow-parent-wp.test b/lldb/test/Shell/Subprocess/fork-follow-parent-wp.test
deleted file mode 100644
index cde5b41f228b..000000000000
--- a/lldb/test/Shell/Subprocess/fork-follow-parent-wp.test
+++ /dev/null
@@ -1,13 +0,0 @@
-# REQUIRES: native && dbregs-set
-# UNSUPPORTED: system-windows
-# RUN: %clangxx_host -g %p/Inputs/fork.cpp -DTEST_FORK=fork -o %t
-# RUN: %lldb -b -s %s %t | FileCheck %s
-process launch -s
-watchpoint set variable -w write g_val
-# CHECK: Watchpoint created:
-continue
-# CHECK-NOT: function run in parent
-# CHECK: stop reason = watchpoint
-continue
-# CHECK: function run in parent
-# CHECK: child exited: 0

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

diff  --git a/lldb/test/Shell/Subprocess/lit.local.cfg b/lldb/test/Shell/Subprocess/lit.local.cfg
deleted file mode 100644
index c9b378b7a8a5..000000000000
--- a/lldb/test/Shell/Subprocess/lit.local.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-if 'lldb-repro' in config.available_features:
-  config.unsupported = True

diff  --git a/lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test b/lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test
deleted file mode 100644
index 8c74e28dbc19..000000000000
--- a/lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test
+++ /dev/null
@@ -1,14 +0,0 @@
-# REQUIRES: native && dbregs-set
-# UNSUPPORTED: system-windows
-# UNSUPPORTED: system-darwin
-# RUN: %clangxx_host -g %p/Inputs/fork.cpp -DTEST_FORK=vfork -o %t
-# RUN: %lldb -b -s %s %t | FileCheck %s
-process launch -s
-watchpoint set variable -w write g_val
-# CHECK: Watchpoint created:
-continue
-# CHECK-NOT: function run in parent
-# CHECK: stop reason = watchpoint
-continue
-# CHECK: function run in parent
-# CHECK: child exited: 0

diff  --git a/lldb/test/Shell/Subprocess/vfork-follow-parent.test b/lldb/test/Shell/Subprocess/vfork-follow-parent.test
deleted file mode 100644
index 6d9850a706e6..000000000000
--- a/lldb/test/Shell/Subprocess/vfork-follow-parent.test
+++ /dev/null
@@ -1,11 +0,0 @@
-# REQUIRES: native
-# 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
-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