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 &x : 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 =================================================================== --- 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();