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<std::unique_ptr<NativeProcessProtocol>>
     Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
            MainLoop &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<lldb::addr_t, lldb::addr_t> 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<NativeProcessProtocol> child_process_up{child_process};
+    Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+    if ((m_enabled_extensions & expected_ext) == expected_ext) {
+      for (auto &x : 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 {
+      child_process_up->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,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();