mgorny created this revision.
mgorny added reviewers: labath, emaste, krytarowski.
mgorny requested review of this revision.
Add a support for handling fork/vfork stops in LLGS client. At this
point, it only sends a detach packet for the newly forked child
(and implicitly resumes the parent).
https://reviews.llvm.org/D100206
Files:
lldb/include/lldb/Target/Process.h
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/source/Target/StopInfo.cpp
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;
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() : "<unknown error>");
+ 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() : "<unknown error>");
+ return;
+ }
+}
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.
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits