Index: lldb/include/lldb/Target/Process.h =================================================================== --- lldb/include/lldb/Target/Process.h +++ lldb/include/lldb/Target/Process.h @@ -978,6 +978,12 @@ /// anything after a process exec's itself. virtual void DoDidExec() {} + /// Called after a reported fork. + virtual void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {} + + /// Called after a reported vfork. + virtual void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {} + /// Called before launching to a process. /// /// Allow Process plug-ins to execute some code before launching a process. Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h =================================================================== --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -230,6 +230,9 @@ std::string HarmonizeThreadIdsForProfileData( StringExtractorGDBRemote &inputStringExtractor); + 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; + protected: friend class ThreadGDBRemote; friend class GDBRemoteCommunicationClient; Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -5432,3 +5432,29 @@ GetTarget().GetDebugger().GetCommandInterpreter()); return m_command_sp.get(); } + +void ProcessGDBRemote::DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + + LLDB_LOG(log, "Detaching forked child {0}", child_pid); + Status error = m_gdb_comm.Detach(false, child_pid); + if (error.Fail()) { + LLDB_LOG(log, + "ProcessGDBRemote::DidFork() detach packet send failed: {0}", + error.AsCString() ? error.AsCString() : ""); + return; + } +} + +void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + + LLDB_LOG(log, "Detaching forked child {0}", child_pid); + Status error = m_gdb_comm.Detach(false, child_pid); + if (error.Fail()) { + LLDB_LOG(log, + "ProcessGDBRemote::DidFork() detach packet send failed: {0}", + error.AsCString() ? error.AsCString() : ""); + return; + } +} Index: lldb/source/Target/StopInfo.cpp =================================================================== --- lldb/source/Target/StopInfo.cpp +++ lldb/source/Target/StopInfo.cpp @@ -1150,8 +1150,8 @@ class StopInfoFork : public StopInfo { public: StopInfoFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid) - : StopInfo(thread, child_pid), m_child_pid(child_pid), - m_child_tid(child_tid) {} + : StopInfo(thread, child_pid), m_performed_action(false), + m_child_pid(child_pid), m_child_tid(child_tid) {} ~StopInfoFork() override = default; @@ -1161,6 +1161,19 @@ const char *GetDescription() override { return "fork"; } +protected: + void PerformAction(Event *event_ptr) override { + // Only perform the action once + if (m_performed_action) + return; + m_performed_action = true; + ThreadSP thread_sp(m_thread_wp.lock()); + if (thread_sp) + thread_sp->GetProcess()->DidFork(m_child_pid, m_child_tid); + } + + bool m_performed_action; + private: lldb::pid_t m_child_pid; lldb::tid_t m_child_tid; @@ -1171,8 +1184,8 @@ class StopInfoVFork : public StopInfo { public: StopInfoVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid) - : StopInfo(thread, child_pid), m_child_pid(child_pid), - m_child_tid(child_tid) {} + : StopInfo(thread, child_pid), m_performed_action(false), + m_child_pid(child_pid), m_child_tid(child_tid) {} ~StopInfoVFork() override = default; @@ -1182,6 +1195,19 @@ const char *GetDescription() override { return "vfork"; } +protected: + void PerformAction(Event *event_ptr) override { + // Only perform the action once + if (m_performed_action) + return; + m_performed_action = true; + ThreadSP thread_sp(m_thread_wp.lock()); + if (thread_sp) + thread_sp->GetProcess()->DidVFork(m_child_pid, m_child_tid); + } + + bool m_performed_action; + private: lldb::pid_t m_child_pid; lldb::tid_t m_child_tid;