mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-25 13:05:04 +00:00
[lldb] [Process/NetBSD] Report fork/vfork events to LLGS
Differential Revision: https://reviews.llvm.org/D100554
This commit is contained in:
parent
65f2a75737
commit
06215023f4
@ -863,7 +863,7 @@ def checkForkVForkSupport():
|
||||
from lldbsuite.test import lldbplatformutil
|
||||
|
||||
platform = lldbplatformutil.getPlatform()
|
||||
if platform not in ["freebsd", "linux"]:
|
||||
if platform not in ["freebsd", "linux", "netbsd"]:
|
||||
configuration.skip_categories.append("fork")
|
||||
|
||||
|
||||
|
@ -133,13 +133,19 @@ NativeProcessNetBSD::Factory::Attach(
|
||||
return std::move(process_up);
|
||||
}
|
||||
|
||||
NativeProcessNetBSD::Extension
|
||||
NativeProcessNetBSD::Factory::GetSupportedExtensions() const {
|
||||
return Extension::multiprocess | Extension::fork | Extension::vfork;
|
||||
}
|
||||
|
||||
// Public Instance Methods
|
||||
|
||||
NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd,
|
||||
NativeDelegate &delegate,
|
||||
const ArchSpec &arch,
|
||||
MainLoop &mainloop)
|
||||
: NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
|
||||
: NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
|
||||
m_main_loop(mainloop) {
|
||||
if (m_terminal_fd != -1) {
|
||||
Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
|
||||
assert(status.Success());
|
||||
@ -264,14 +270,23 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(thread);
|
||||
if (pst.pe_report_event == PTRACE_VFORK_DONE) {
|
||||
Status error =
|
||||
PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
|
||||
if (error.Fail())
|
||||
SetState(StateType::eStateInvalid);
|
||||
return;
|
||||
} else
|
||||
MonitorClone(pst.pe_other_pid);
|
||||
if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) {
|
||||
thread->SetStoppedByVForkDone();
|
||||
SetState(StateType::eStateStopped, true);
|
||||
} else {
|
||||
Status error =
|
||||
PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
|
||||
if (error.Fail())
|
||||
SetState(StateType::eStateInvalid);
|
||||
}
|
||||
} else {
|
||||
assert(pst.pe_report_event == PTRACE_FORK ||
|
||||
pst.pe_report_event == PTRACE_VFORK);
|
||||
MonitorClone(pst.pe_other_pid, pst.pe_report_event == PTRACE_VFORK,
|
||||
*thread);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TRAP_LWP: {
|
||||
@ -994,7 +1009,8 @@ Status NativeProcessNetBSD::ReinitializeThreads() {
|
||||
return error;
|
||||
}
|
||||
|
||||
void NativeProcessNetBSD::MonitorClone(::pid_t child_pid) {
|
||||
void NativeProcessNetBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
|
||||
NativeThreadNetBSD &parent_thread) {
|
||||
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
|
||||
LLDB_LOG(log, "clone, child_pid={0}", child_pid);
|
||||
|
||||
@ -1016,16 +1032,43 @@ void NativeProcessNetBSD::MonitorClone(::pid_t child_pid) {
|
||||
return;
|
||||
}
|
||||
|
||||
MainLoop unused_loop;
|
||||
NativeProcessNetBSD child_process{static_cast<::pid_t>(child_pid),
|
||||
m_terminal_fd, m_delegate, m_arch,
|
||||
unused_loop};
|
||||
child_process.Detach();
|
||||
Status pt_error =
|
||||
PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0);
|
||||
if (pt_error.Fail()) {
|
||||
LLDB_LOG_ERROR(log, std::move(pt_error.ToError()),
|
||||
"unable to resume parent process {1}: {0}", GetID());
|
||||
SetState(StateType::eStateInvalid);
|
||||
ptrace_siginfo_t info;
|
||||
const auto siginfo_err =
|
||||
PtraceWrapper(PT_GET_SIGINFO, child_pid, &info, sizeof(info));
|
||||
if (siginfo_err.Fail()) {
|
||||
LLDB_LOG(log, "PT_GET_SIGINFO failed {0}", siginfo_err);
|
||||
return;
|
||||
}
|
||||
assert(info.psi_lwpid >= 0);
|
||||
lldb::tid_t child_tid = info.psi_lwpid;
|
||||
|
||||
std::unique_ptr<NativeProcessNetBSD> child_process{
|
||||
new NativeProcessNetBSD(static_cast<::pid_t>(child_pid), m_terminal_fd,
|
||||
m_delegate, m_arch, m_main_loop)};
|
||||
if (!is_vfork)
|
||||
child_process->m_software_breakpoints = m_software_breakpoints;
|
||||
|
||||
Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
|
||||
if ((m_enabled_extensions & expected_ext) == expected_ext) {
|
||||
child_process->SetupTrace();
|
||||
for (const auto &thread : child_process->m_threads)
|
||||
static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
|
||||
child_process->SetState(StateType::eStateStopped, false);
|
||||
|
||||
m_delegate.NewSubprocess(this, std::move(child_process));
|
||||
if (is_vfork)
|
||||
parent_thread.SetStoppedByVFork(child_pid, child_tid);
|
||||
else
|
||||
parent_thread.SetStoppedByFork(child_pid, child_tid);
|
||||
SetState(StateType::eStateStopped, true);
|
||||
} else {
|
||||
child_process->Detach();
|
||||
Status pt_error =
|
||||
PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0);
|
||||
if (pt_error.Fail()) {
|
||||
LLDB_LOG_ERROR(log, std::move(pt_error.ToError()),
|
||||
"unable to resume parent process {1}: {0}", GetID());
|
||||
SetState(StateType::eStateInvalid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
|
||||
Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
|
||||
MainLoop &mainloop) const override;
|
||||
|
||||
Extension GetSupportedExtensions() const override;
|
||||
};
|
||||
|
||||
// NativeProcessProtocol Interface
|
||||
@ -89,6 +91,7 @@ public:
|
||||
private:
|
||||
MainLoop::SignalHandleUP m_sigchld_handle;
|
||||
ArchSpec m_arch;
|
||||
MainLoop& m_main_loop;
|
||||
LazyBool m_supports_mem_region = eLazyBoolCalculate;
|
||||
std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
|
||||
|
||||
@ -106,7 +109,8 @@ private:
|
||||
void MonitorSIGSTOP(lldb::pid_t pid);
|
||||
void MonitorSIGTRAP(lldb::pid_t pid);
|
||||
void MonitorSignal(lldb::pid_t pid, int signal);
|
||||
void MonitorClone(::pid_t child_pid);
|
||||
void MonitorClone(::pid_t child_pid, bool is_vfork,
|
||||
NativeThreadNetBSD &parent_thread);
|
||||
|
||||
Status PopulateMemoryRegionCache();
|
||||
void SigchldHandler();
|
||||
|
@ -130,6 +130,30 @@ void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
|
||||
m_stop_info.details.signal.signo = SIGTRAP;
|
||||
}
|
||||
|
||||
void NativeThreadNetBSD::SetStoppedByFork(lldb::pid_t child_pid,
|
||||
lldb::tid_t child_tid) {
|
||||
SetStopped();
|
||||
|
||||
m_stop_info.reason = StopReason::eStopReasonFork;
|
||||
m_stop_info.details.fork.child_pid = child_pid;
|
||||
m_stop_info.details.fork.child_tid = child_tid;
|
||||
}
|
||||
|
||||
void NativeThreadNetBSD::SetStoppedByVFork(lldb::pid_t child_pid,
|
||||
lldb::tid_t child_tid) {
|
||||
SetStopped();
|
||||
|
||||
m_stop_info.reason = StopReason::eStopReasonVFork;
|
||||
m_stop_info.details.fork.child_pid = child_pid;
|
||||
m_stop_info.details.fork.child_tid = child_tid;
|
||||
}
|
||||
|
||||
void NativeThreadNetBSD::SetStoppedByVForkDone() {
|
||||
SetStopped();
|
||||
|
||||
m_stop_info.reason = StopReason::eStopReasonVForkDone;
|
||||
}
|
||||
|
||||
void NativeThreadNetBSD::SetStoppedWithNoReason() {
|
||||
SetStopped();
|
||||
|
||||
|
@ -59,6 +59,9 @@ private:
|
||||
void SetStoppedByTrace();
|
||||
void SetStoppedByExec();
|
||||
void SetStoppedByWatchpoint(uint32_t wp_index);
|
||||
void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
|
||||
void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
|
||||
void SetStoppedByVForkDone();
|
||||
void SetStoppedWithNoReason();
|
||||
void SetStopped();
|
||||
void SetRunning();
|
||||
|
Loading…
x
Reference in New Issue
Block a user