mgorny created this revision.
mgorny added reviewers: labath, emaste, krytarowski.
mgorny requested review of this revision.
https://reviews.llvm.org/D100554
Files:
lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
lldb/test/Shell/Subprocess/clone-follow-child-softbp.test
lldb/test/Shell/Subprocess/clone-follow-child-wp.test
lldb/test/Shell/Subprocess/clone-follow-child.test
Index: lldb/test/Shell/Subprocess/clone-follow-child.test
===================================================================
--- lldb/test/Shell/Subprocess/clone-follow-child.test
+++ lldb/test/Shell/Subprocess/clone-follow-child.test
@@ -1,4 +1,4 @@
-# REQUIRES: native && (system-linux || system-netbsd)
+# REQUIRES: native && system-linux
# clone() tests fails on arm64 Linux, PR #49899
# UNSUPPORTED: system-linux && target-aarch64
# RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_CLONE -o %t
Index: lldb/test/Shell/Subprocess/clone-follow-child-wp.test
===================================================================
--- lldb/test/Shell/Subprocess/clone-follow-child-wp.test
+++ lldb/test/Shell/Subprocess/clone-follow-child-wp.test
@@ -1,4 +1,4 @@
-# REQUIRES: native && (system-linux || system-netbsd) && dbregs-set
+# REQUIRES: native && system-linux && dbregs-set
# clone() tests fails on arm64 Linux, PR #49899
# UNSUPPORTED: system-linux && target-aarch64
# RUN: %clangxx_host -g %p/Inputs/fork.cpp -DTEST_CLONE -o %t
Index: lldb/test/Shell/Subprocess/clone-follow-child-softbp.test
===================================================================
--- lldb/test/Shell/Subprocess/clone-follow-child-softbp.test
+++ lldb/test/Shell/Subprocess/clone-follow-child-softbp.test
@@ -1,4 +1,4 @@
-# REQUIRES: native && (system-linux || system-netbsd)
+# REQUIRES: native && system-linux
# clone() tests fails on arm64 Linux, PR #49899
# UNSUPPORTED: system-linux && target-aarch64
# RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_CLONE -o %t
Index: lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+++ lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
@@ -59,6 +59,9 @@
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();
Index: lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -130,6 +130,30 @@
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();
Index: lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -36,6 +36,8 @@
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 @@
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 @@
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();
Index: lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -133,13 +133,19 @@
return std::move(process_up);
}
+NativeProcessNetBSD::Extension
+NativeProcessNetBSD::Factory::GetSupportedExtensions() const {
+ return 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 @@
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 @@
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,44 @@
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;
+
+ 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;
+
+ std::unique_ptr<NativeProcessProtocol> child_process_up{child_process};
+ 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, child_process_up);
+ 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_up->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);
+ }
}
}
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits