[Lldb-commits] [lldb] 6c37984 - [lldb] [gdb-remote server] Introduce new stop reasons for fork and vfork
Michał Górny via lldb-commits
lldb-commits at lists.llvm.org
Sat Apr 24 02:26:36 PDT 2021
Author: Michał Górny
Date: 2021-04-24T11:08:33+02:00
New Revision: 6c37984ebaf4ee01df6a9b3f78e45f70dcd6fb33
URL: https://github.com/llvm/llvm-project/commit/6c37984ebaf4ee01df6a9b3f78e45f70dcd6fb33
DIFF: https://github.com/llvm/llvm-project/commit/6c37984ebaf4ee01df6a9b3f78e45f70dcd6fb33.diff
LOG: [lldb] [gdb-remote server] Introduce new stop reasons for fork and vfork
Introduce three new stop reasons for fork, vfork and vforkdone events.
This includes server support for serializing fork/vfork events into
gdb-remote protocol. The stop infos for the two base events take a pair
of PID and TID for the newly forked process.
Differential Revision: https://reviews.llvm.org/D100196
Added:
Modified:
lldb/bindings/interface/SBThread.i
lldb/bindings/interface/SBThreadPlan.i
lldb/docs/python_api_enums.rst
lldb/examples/python/performance.py
lldb/include/lldb/API/SBThread.h
lldb/include/lldb/API/SBThreadPlan.h
lldb/include/lldb/Host/Debug.h
lldb/include/lldb/lldb-enumerations.h
lldb/packages/Python/lldbsuite/test/lldbutil.py
lldb/source/API/SBThread.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
lldb/source/Target/Process.cpp
lldb/source/Target/StackFrameList.cpp
lldb/source/Target/Thread.cpp
lldb/tools/lldb-vscode/JSONUtils.cpp
lldb/tools/lldb-vscode/LLDBUtils.cpp
Removed:
################################################################################
diff --git a/lldb/bindings/interface/SBThread.i b/lldb/bindings/interface/SBThread.i
index 463584d2cab16..d847d38f0d66e 100644
--- a/lldb/bindings/interface/SBThread.i
+++ b/lldb/bindings/interface/SBThread.i
@@ -104,6 +104,9 @@ public:
eStopReasonSignal 1 unix signal number
eStopReasonException N exception data
eStopReasonExec 0
+ eStopReasonFork 1 pid of the child process
+ eStopReasonVFork 1 pid of the child process
+ eStopReasonVForkDone 0
eStopReasonPlanComplete 0") GetStopReasonDataAtIndex;
uint64_t
GetStopReasonDataAtIndex(uint32_t idx);
diff --git a/lldb/bindings/interface/SBThreadPlan.i b/lldb/bindings/interface/SBThreadPlan.i
index 94ae1a42dd3b2..9e10535253548 100644
--- a/lldb/bindings/interface/SBThreadPlan.i
+++ b/lldb/bindings/interface/SBThreadPlan.i
@@ -73,6 +73,9 @@ public:
eStopReasonSignal 1 unix signal number
eStopReasonException N exception data
eStopReasonExec 0
+ eStopReasonFork 1 pid of the child process
+ eStopReasonVFork 1 pid of the child process
+ eStopReasonVForkDone 0
eStopReasonPlanComplete 0") GetStopReasonDataAtIndex;
uint64_t
GetStopReasonDataAtIndex(uint32_t idx);
diff --git a/lldb/docs/python_api_enums.rst b/lldb/docs/python_api_enums.rst
index a05647f61ca8c..70bce246fc687 100644
--- a/lldb/docs/python_api_enums.rst
+++ b/lldb/docs/python_api_enums.rst
@@ -342,6 +342,9 @@ StopReason
.. py:data:: eStopReasonSignal
.. py:data:: eStopReasonException
.. py:data:: eStopReasonExec
+.. py:data:: eStopReasonFork
+.. py:data:: eStopReasonVFork
+.. py:data:: eStopReasonVForkDone
.. py:data:: eStopReasonPlanComplete
.. py:data:: eStopReasonThreadExiting
.. py:data:: eStopReasonInstrumentation
diff --git a/lldb/examples/python/performance.py b/lldb/examples/python/performance.py
index f90857808fc0c..57e9d1e0a24c3 100755
--- a/lldb/examples/python/performance.py
+++ b/lldb/examples/python/performance.py
@@ -255,6 +255,15 @@ def WaitForNextProcessEvent(self):
select_thread = True
if self.verbose:
print("signal %d" % (thread.GetStopReasonDataAtIndex(0)))
+ elif stop_reason == lldb.eStopReasonFork:
+ if self.verbose:
+ print("fork pid = %d" % (thread.GetStopReasonDataAtIndex(0)))
+ elif stop_reason == lldb.eStopReasonVFork:
+ if self.verbose:
+ print("vfork pid = %d" % (thread.GetStopReasonDataAtIndex(0)))
+ elif stop_reason == lldb.eStopReasonVForkDone:
+ if self.verbose:
+ print("vfork done")
if select_thread and not selected_thread:
self.thread = thread
diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h
index 894120c6d9861..095a679948227 100644
--- a/lldb/include/lldb/API/SBThread.h
+++ b/lldb/include/lldb/API/SBThread.h
@@ -66,6 +66,9 @@ class LLDB_API SBThread {
/// eStopReasonSignal 1 unix signal number
/// eStopReasonException N exception data
/// eStopReasonExec 0
+ /// eStopReasonFork 1 pid of the child process
+ /// eStopReasonVFork 1 pid of the child process
+ /// eStopReasonVForkDone 0
/// eStopReasonPlanComplete 0
uint64_t GetStopReasonDataAtIndex(uint32_t idx);
diff --git a/lldb/include/lldb/API/SBThreadPlan.h b/lldb/include/lldb/API/SBThreadPlan.h
index 269cbc64a8efd..831452dc0a98d 100644
--- a/lldb/include/lldb/API/SBThreadPlan.h
+++ b/lldb/include/lldb/API/SBThreadPlan.h
@@ -58,6 +58,9 @@ class LLDB_API SBThreadPlan {
/// eStopReasonSignal 1 unix signal number
/// eStopReasonException N exception data
/// eStopReasonExec 0
+ /// eStopReasonFork 1 pid of the child process
+ /// eStopReasonVFork 1 pid of the child process
+ /// eStopReasonVForkDone 0
/// eStopReasonPlanComplete 0
uint64_t GetStopReasonDataAtIndex(uint32_t idx);
diff --git a/lldb/include/lldb/Host/Debug.h b/lldb/include/lldb/Host/Debug.h
index 402325c4c166e..7da59dd04a66b 100644
--- a/lldb/include/lldb/Host/Debug.h
+++ b/lldb/include/lldb/Host/Debug.h
@@ -144,6 +144,12 @@ struct ThreadStopInfo {
uint32_t data_count;
lldb::addr_t data[8];
} exception;
+
+ // eStopReasonFork / eStopReasonVFork
+ struct {
+ lldb::pid_t child_pid;
+ lldb::tid_t child_tid;
+ } fork;
} details;
};
}
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index dcd022b38eb9b..64901ba1476ef 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -249,6 +249,9 @@ enum StopReason {
eStopReasonThreadExiting,
eStopReasonInstrumentation,
eStopReasonProcessorTrace,
+ eStopReasonFork,
+ eStopReasonVFork,
+ eStopReasonVForkDone,
};
/// Command Return Status Types.
diff --git a/lldb/packages/Python/lldbsuite/test/lldbutil.py b/lldb/packages/Python/lldbsuite/test/lldbutil.py
index 5fff3726a65e6..20a6d28274b3d 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbutil.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbutil.py
@@ -252,6 +252,12 @@ def stop_reason_to_str(enum):
return "watchpoint"
elif enum == lldb.eStopReasonExec:
return "exec"
+ elif enum == lldb.eStopReasonFork:
+ return "fork"
+ elif enum == lldb.eStopReasonVFork:
+ return "vfork"
+ elif enum == lldb.eStopReasonVForkDone:
+ return "vforkdone"
elif enum == lldb.eStopReasonSignal:
return "signal"
elif enum == lldb.eStopReasonException:
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 4a1b53d4a5927..7b3d93905cce5 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -173,6 +173,7 @@ size_t SBThread::GetStopReasonDataCount() {
case eStopReasonThreadExiting:
case eStopReasonInstrumentation:
case eStopReasonProcessorTrace:
+ case eStopReasonVForkDone:
// There is no data for these stop reasons.
return 0;
@@ -195,6 +196,12 @@ size_t SBThread::GetStopReasonDataCount() {
case eStopReasonException:
return 1;
+
+ case eStopReasonFork:
+ return 1;
+
+ case eStopReasonVFork:
+ return 1;
}
}
}
@@ -225,6 +232,7 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
case eStopReasonThreadExiting:
case eStopReasonInstrumentation:
case eStopReasonProcessorTrace:
+ case eStopReasonVForkDone:
// There is no data for these stop reasons.
return 0;
@@ -258,6 +266,12 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
case eStopReasonException:
return stop_info_sp->GetValue();
+
+ case eStopReasonFork:
+ return stop_info_sp->GetValue();
+
+ case eStopReasonVFork:
+ return stop_info_sp->GetValue();
}
}
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 6694e99267b3c..49f560122e514 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -659,6 +659,12 @@ static const char *GetStopReasonString(StopReason stop_reason) {
return "exec";
case eStopReasonProcessorTrace:
return "processor trace";
+ case eStopReasonFork:
+ return "fork";
+ case eStopReasonVFork:
+ return "vfork";
+ case eStopReasonVForkDone:
+ return "vforkdone";
case eStopReasonInstrumentation:
case eStopReasonInvalid:
case eStopReasonPlanComplete:
@@ -934,6 +940,22 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
}
}
+ // Include child process PID/TID for forks.
+ if (tid_stop_info.reason == eStopReasonFork ||
+ tid_stop_info.reason == eStopReasonVFork) {
+ assert(bool(m_extensions_supported &
+ NativeProcessProtocol::Extension::multiprocess));
+ if (tid_stop_info.reason == eStopReasonFork)
+ assert(bool(m_extensions_supported &
+ NativeProcessProtocol::Extension::fork));
+ if (tid_stop_info.reason == eStopReasonVFork)
+ assert(bool(m_extensions_supported &
+ NativeProcessProtocol::Extension::vfork));
+ response.Printf("%s:p%" PRIx64 ".%" PRIx64 ";", reason_str,
+ tid_stop_info.details.fork.child_pid,
+ tid_stop_info.details.fork.child_tid);
+ }
+
return SendPacketNoLock(response.GetString());
}
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 5af8567733e3d..a5a3f8126e642 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -822,6 +822,9 @@ bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp,
case eStopReasonWatchpoint:
case eStopReasonException:
case eStopReasonExec:
+ case eStopReasonFork:
+ case eStopReasonVFork:
+ case eStopReasonVForkDone:
case eStopReasonThreadExiting:
case eStopReasonInstrumentation:
case eStopReasonProcessorTrace:
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp
index ed40356bef604..061500152a499 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -131,6 +131,9 @@ void StackFrameList::ResetCurrentInlinedDepth() {
case eStopReasonWatchpoint:
case eStopReasonException:
case eStopReasonExec:
+ case eStopReasonFork:
+ case eStopReasonVFork:
+ case eStopReasonVForkDone:
case eStopReasonSignal:
// In all these cases we want to stop in the deepest frame.
m_current_inlined_pc = curr_pc;
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index 57cfaddac6d23..b423f1b5f1fe2 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -1679,6 +1679,12 @@ std::string Thread::StopReasonAsString(lldb::StopReason reason) {
return "exception";
case eStopReasonExec:
return "exec";
+ case eStopReasonFork:
+ return "fork";
+ case eStopReasonVFork:
+ return "vfork";
+ case eStopReasonVForkDone:
+ return "vfork done";
case eStopReasonPlanComplete:
return "plan complete";
case eStopReasonThreadExiting:
diff --git a/lldb/tools/lldb-vscode/JSONUtils.cpp b/lldb/tools/lldb-vscode/JSONUtils.cpp
index 6894ec0fff839..a64e9778074a0 100644
--- a/lldb/tools/lldb-vscode/JSONUtils.cpp
+++ b/lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -878,6 +878,15 @@ llvm::json::Value CreateThreadStopped(lldb::SBThread &thread,
case lldb::eStopReasonExec:
body.try_emplace("reason", "entry");
break;
+ case lldb::eStopReasonFork:
+ body.try_emplace("reason", "fork");
+ break;
+ case lldb::eStopReasonVFork:
+ body.try_emplace("reason", "vfork");
+ break;
+ case lldb::eStopReasonVForkDone:
+ body.try_emplace("reason", "vforkdone");
+ break;
case lldb::eStopReasonThreadExiting:
case lldb::eStopReasonInvalid:
case lldb::eStopReasonNone:
diff --git a/lldb/tools/lldb-vscode/LLDBUtils.cpp b/lldb/tools/lldb-vscode/LLDBUtils.cpp
index a5bc400dfccce..621f4ec37c83d 100644
--- a/lldb/tools/lldb-vscode/LLDBUtils.cpp
+++ b/lldb/tools/lldb-vscode/LLDBUtils.cpp
@@ -56,6 +56,9 @@ bool ThreadHasStopReason(lldb::SBThread &thread) {
case lldb::eStopReasonException:
case lldb::eStopReasonExec:
case lldb::eStopReasonProcessorTrace:
+ case lldb::eStopReasonFork:
+ case lldb::eStopReasonVFork:
+ case lldb::eStopReasonVForkDone:
return true;
case lldb::eStopReasonThreadExiting:
case lldb::eStopReasonInvalid:
More information about the lldb-commits
mailing list