diff options
author | Michał Górny <mgorny@moritz.systems> | 2021-04-13 13:59:05 +0200 |
---|---|---|
committer | Michał Górny <mgorny@moritz.systems> | 2021-04-13 14:35:44 +0200 |
commit | 7da3b44d67f81e4cff3ac4f72888e667bd9e6adb (patch) | |
tree | eccaf6b9c099b523fabe473453eb7968dbe8002d /lldb | |
parent | [libc++] Move pointer safety related utilities out of <memory> (diff) | |
download | llvm-project-7da3b44d67f81e4cff3ac4f72888e667bd9e6adb.tar.gz llvm-project-7da3b44d67f81e4cff3ac4f72888e667bd9e6adb.tar.bz2 llvm-project-7da3b44d67f81e4cff3ac4f72888e667bd9e6adb.zip |
Reland "[lldb] [Process] Watch for fork/vfork notifications" for NetBSD
Differential Revision: https://reviews.llvm.org/D98822
Diffstat (limited to 'lldb')
4 files changed, 87 insertions, 5 deletions
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 57f0eb3cceb6..1f357e3e96d7 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -256,6 +256,24 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) { SetState(StateType::eStateStopped, true); return; } + case TRAP_CHLD: { + ptrace_state_t pst; + Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst)); + if (error.Fail()) { + SetState(StateType::eStateInvalid); + return; + } + + 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); + return; + } case TRAP_LWP: { ptrace_state_t pst; Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst)); @@ -510,7 +528,7 @@ Status NativeProcessNetBSD::Detach() { if (GetID() == LLDB_INVALID_PROCESS_ID) return error; - return PtraceWrapper(PT_DETACH, GetID()); + return PtraceWrapper(PT_DETACH, GetID(), reinterpret_cast<void *>(1)); } Status NativeProcessNetBSD::Signal(int signo) { @@ -738,17 +756,17 @@ Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name, void NativeProcessNetBSD::SigchldHandler() { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); - // Process all pending waitpid notifications. int status; ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WALLSIG | WNOHANG); if (wait_pid == 0) - return; // We are done. + return; if (wait_pid == -1) { Status error(errno, eErrorTypePOSIX); LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error); + return; } WaitStatus wait_status = WaitStatus::Decode(status); @@ -936,8 +954,9 @@ Status NativeProcessNetBSD::SetupTrace() { PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events)); if (status.Fail()) return status; - // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN? - events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT; + // TODO: PTRACE_POSIX_SPAWN? + events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT | PTRACE_FORK | + PTRACE_VFORK | PTRACE_VFORK_DONE; status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events)); if (status.Fail()) return status; @@ -974,3 +993,39 @@ Status NativeProcessNetBSD::ReinitializeThreads() { return error; } + +void NativeProcessNetBSD::MonitorClone(::pid_t child_pid) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + LLDB_LOG(log, "clone, child_pid={0}", child_pid); + + int status; + ::pid_t wait_pid = + llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0); + if (wait_pid != child_pid) { + LLDB_LOG(log, + "waiting for pid {0} failed. Assuming the pid has " + "disappeared in the meantime", + child_pid); + return; + } + if (WIFEXITED(status)) { + LLDB_LOG(log, + "waiting for pid {0} returned an 'exited' event. Not " + "tracking it.", + 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); + } +} diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h index 3d59a4f72e94..3384078a0d6d 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h +++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h @@ -106,6 +106,7 @@ 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); Status PopulateMemoryRegionCache(); void SigchldHandler(); diff --git a/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test b/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test new file mode 100644 index 000000000000..19fa7d6f1a32 --- /dev/null +++ b/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test @@ -0,0 +1,14 @@ +# REQUIRES: native && system-netbsd && 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 +# RUN: %lldb -b -s %s %t | FileCheck %s +process launch -s +watchpoint set variable -w write g_val +# CHECK: Watchpoint created: +continue +# CHECK-NOT: function run in parent +# CHECK: stop reason = watchpoint +continue +# CHECK: function run in parent +# CHECK: child exited: 0 diff --git a/lldb/test/Shell/Subprocess/clone-follow-parent.test b/lldb/test/Shell/Subprocess/clone-follow-parent.test new file mode 100644 index 000000000000..3d89279bbb29 --- /dev/null +++ b/lldb/test/Shell/Subprocess/clone-follow-parent.test @@ -0,0 +1,12 @@ +# REQUIRES: native && (system-linux || system-netbsd) +# clone() tests fails on arm64 Linux, PR #49899 +# UNSUPPORTED: system-linux && target-aarch64 +# RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_CLONE -o %t +# RUN: %lldb -b -s %s %t | FileCheck %s +b parent_func +process launch +# CHECK-NOT: function run in parent +# CHECK: stop reason = breakpoint +continue +# CHECK: function run in parent +# CHECK: child exited: 0 |