[Lldb-commits] [lldb] 65f2a75 - [lldb] [Process/FreeBSD] Report fork/vfork events to LLGS
Michał Górny via lldb-commits
lldb-commits at lists.llvm.org
Sun Apr 25 10:41:21 PDT 2021
Author: Michał Górny
Date: 2021-04-25T19:40:46+02:00
New Revision: 65f2a757371e687cee6c36788fde1dab22895df7
URL: https://github.com/llvm/llvm-project/commit/65f2a757371e687cee6c36788fde1dab22895df7
DIFF: https://github.com/llvm/llvm-project/commit/65f2a757371e687cee6c36788fde1dab22895df7.diff
LOG: [lldb] [Process/FreeBSD] Report fork/vfork events to LLGS
Differential Revision: https://reviews.llvm.org/D100547
Added:
Modified:
lldb/packages/Python/lldbsuite/test/dotest.py
lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
Removed:
################################################################################
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index b3a6fb318d969..d48c578d7d75d 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -863,7 +863,7 @@ def checkForkVForkSupport():
from lldbsuite.test import lldbplatformutil
platform = lldbplatformutil.getPlatform()
- if platform not in ["linux"]:
+ if platform not in ["freebsd", "linux"]:
configuration.skip_categories.append("fork")
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
index 67a7b737c7d6c..6d9a7d7f0d9c1 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
@@ -128,13 +128,19 @@ NativeProcessFreeBSD::Factory::Attach(
return std::move(process_up);
}
+NativeProcessFreeBSD::Extension
+NativeProcessFreeBSD::Factory::GetSupportedExtensions() const {
+ return Extension::multiprocess | Extension::fork | Extension::vfork;
+}
+
// Public Instance Methods
NativeProcessFreeBSD::NativeProcessFreeBSD(::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());
@@ -247,19 +253,6 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
return;
}
- if (info.pl_flags & PL_FLAG_FORKED) {
- MonitorClone(info.pl_child_pid);
- return;
- }
-
- if (info.pl_flags & PL_FLAG_VFORK_DONE) {
- Status error =
- PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
- if (error.Fail())
- SetState(StateType::eStateInvalid);
- return;
- }
-
if (info.pl_lwpid > 0) {
for (const auto &t : m_threads) {
if (t->GetID() == static_cast<lldb::tid_t>(info.pl_lwpid))
@@ -271,6 +264,26 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
info.pl_lwpid);
}
+ if (info.pl_flags & PL_FLAG_FORKED) {
+ assert(thread);
+ MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread);
+ return;
+ }
+
+ if (info.pl_flags & PL_FLAG_VFORK_DONE) {
+ assert(thread);
+ 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);
+ }
+ return;
+ }
+
if (info.pl_flags & PL_FLAG_SI) {
assert(info.pl_siginfo.si_signo == SIGTRAP);
LLDB_LOG(log, "SIGTRAP siginfo: si_code = {0}, pid = {1}",
@@ -933,7 +946,8 @@ bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const {
return !m_arch.IsMIPS();
}
-void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid) {
+void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
+ NativeThreadFreeBSD &parent_thread) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
LLDB_LOG(log, "fork, child_pid={0}", child_pid);
@@ -955,16 +969,42 @@ void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid) {
return;
}
- MainLoop unused_loop;
- NativeProcessFreeBSD 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, pt_error.ToError(),
- "unable to resume parent process {1}: {0}", GetID());
- SetState(StateType::eStateInvalid);
+ struct ptrace_lwpinfo info;
+ const auto siginfo_err = PtraceWrapper(PT_LWPINFO, child_pid, &info, sizeof(info));
+ if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
+ return;
+ }
+ assert(info.pl_event == PL_EVENT_SIGNAL);
+ lldb::tid_t child_tid = info.pl_lwpid;
+
+ std::unique_ptr<NativeProcessFreeBSD> child_process{
+ new NativeProcessFreeBSD(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<NativeThreadFreeBSD &>(*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, pt_error.ToError(),
+ "unable to resume parent process {1}: {0}", GetID());
+ SetState(StateType::eStateInvalid);
+ }
}
}
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
index 3ed5f743deba2..7ec9d17d4cf48 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
@@ -39,6 +39,8 @@ class NativeProcessFreeBSD : public NativeProcessELF,
llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
MainLoop &mainloop) const override;
+
+ Extension GetSupportedExtensions() const override;
};
// NativeProcessProtocol Interface
@@ -96,6 +98,7 @@ class NativeProcessFreeBSD : public NativeProcessELF,
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;
@@ -113,7 +116,8 @@ class NativeProcessFreeBSD : public NativeProcessELF,
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,
+ NativeThreadFreeBSD &parent_thread);
Status PopulateMemoryRegionCache();
void SigchldHandler();
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
index 63be12fc7b2b0..80b3527aebced 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
@@ -130,6 +130,30 @@ void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
m_stop_info.details.signal.signo = SIGTRAP;
}
+void NativeThreadFreeBSD::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 NativeThreadFreeBSD::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 NativeThreadFreeBSD::SetStoppedByVForkDone() {
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonVForkDone;
+}
+
void NativeThreadFreeBSD::SetStoppedWithNoReason() {
SetStopped();
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
index 249d2486b4f73..3ec6daa409e44 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
@@ -59,6 +59,9 @@ class NativeThreadFreeBSD : public NativeThreadProtocol {
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();
More information about the lldb-commits
mailing list