summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
diff options
context:
space:
mode:
authorMichał Górny <mgorny@moritz.systems>2021-04-09 17:00:12 +0200
committerMichał Górny <mgorny@moritz.systems>2021-04-24 11:08:34 +0200
commitfd0af0cf08284de79fe1a5bcfdc2dad83794dcfe (patch)
tree6e56f2694995c8fd15c78d322330d24cb3252d1e /lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
parentbbae0c1f7b4f60e9b8ac2be24e35bec79d9b7b01 (diff)
[lldb] [Process/Linux] Report fork/vfork stop reason
Enable reporting fork/vfork events to the server when supported. At this moment, this is used only to test the server code, as real client does not report fork-events and vfork-events as supported. Differential Revision: https://reviews.llvm.org/D100208
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp42
1 files changed, 30 insertions, 12 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 40ba5e2e604b..86c5a093b643 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -281,6 +281,11 @@ NativeProcessLinux::Factory::Attach(
pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
}
+NativeProcessLinux::Extension
+NativeProcessLinux::Factory::GetSupportedExtensions() const {
+ return Extension::multiprocess | Extension::fork | Extension::vfork;
+}
+
// Public Instance Methods
NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
@@ -288,7 +293,7 @@ NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
const ArchSpec &arch, MainLoop &mainloop,
llvm::ArrayRef<::pid_t> tids)
: NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
- m_intel_pt_manager(pid) {
+ m_main_loop(mainloop), m_intel_pt_manager(pid) {
if (m_terminal_fd != -1) {
Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
assert(status.Success());
@@ -647,7 +652,12 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
}
case (SIGTRAP | (PTRACE_EVENT_VFORK_DONE << 8)): {
- ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+ if (bool(m_enabled_extensions & Extension::vfork)) {
+ thread.SetStoppedByVForkDone();
+ StopRunningThreads(thread.GetID());
+ }
+ else
+ ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
break;
}
@@ -912,16 +922,24 @@ bool NativeProcessLinux::MonitorClone(
LLVM_FALLTHROUGH;
case PTRACE_EVENT_FORK:
case PTRACE_EVENT_VFORK: {
- MainLoop unused_loop;
- NativeProcessLinux child_process{static_cast<::pid_t>(child_pid),
- m_terminal_fd,
- m_delegate,
- m_arch,
- unused_loop,
- {static_cast<::pid_t>(child_pid)}};
- child_process.Detach();
- ResumeThread(*parent_thread, parent_thread->GetState(),
- LLDB_INVALID_SIGNAL_NUMBER);
+ bool is_vfork = clone_info->event == PTRACE_EVENT_VFORK;
+ std::unique_ptr<NativeProcessLinux> child_process{new NativeProcessLinux(
+ static_cast<::pid_t>(child_pid), m_terminal_fd, m_delegate, m_arch,
+ m_main_loop, {static_cast<::pid_t>(child_pid)})};
+ if (!is_vfork)
+ child_process->m_software_breakpoints = m_software_breakpoints;
+
+ Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+ if (bool(m_enabled_extensions & expected_ext)) {
+ m_delegate.NewSubprocess(this, std::move(child_process));
+ // NB: non-vfork clone() is reported as fork
+ parent_thread->SetStoppedByFork(is_vfork, child_pid);
+ StopRunningThreads(parent_thread->GetID());
+ } else {
+ child_process->Detach();
+ ResumeThread(*parent_thread, parent_thread->GetState(),
+ LLDB_INVALID_SIGNAL_NUMBER);
+ }
break;
}
default: