mirror of
https://github.com/intel/llvm.git
synced 2026-01-15 12:25:46 +08:00
[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
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -255,6 +255,15 @@ class TestCase:
|
||||
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
|
||||
|
||||
@@ -66,6 +66,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
|
||||
uint64_t GetStopReasonDataAtIndex(uint32_t idx);
|
||||
|
||||
|
||||
@@ -58,6 +58,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
|
||||
uint64_t GetStopReasonDataAtIndex(uint32_t idx);
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -249,6 +249,9 @@ enum StopReason {
|
||||
eStopReasonThreadExiting,
|
||||
eStopReasonInstrumentation,
|
||||
eStopReasonProcessorTrace,
|
||||
eStopReasonFork,
|
||||
eStopReasonVFork,
|
||||
eStopReasonVForkDone,
|
||||
};
|
||||
|
||||
/// Command Return Status Types.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user