aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Górny <mgorny@moritz.systems>2021-04-11 17:16:43 +0200
committerMichał Górny <mgorny@moritz.systems>2021-09-01 08:16:12 +0200
commit199344d832c1bed1d75b1db2c1493e5a3e5c5544 (patch)
tree9738c4584b3a714d32d5a962455684eb7d287d9f
parentff780014b29617c54493a21e3a05cac35e448026 (diff)
downloadllvm-199344d832c1bed1d75b1db2c1493e5a3e5c5544.zip
llvm-199344d832c1bed1d75b1db2c1493e5a3e5c5544.tar.gz
llvm-199344d832c1bed1d75b1db2c1493e5a3e5c5544.tar.bz2
[lldb] [gdb-remote client] Remove breakpoints throughout vfork
Temporarily remove breakpoints for the duration of vfork, in order to prevent them from triggering in the child process. Restore them once the server reports that vfork has finished and it is ready to resume execution. Differential Revision: https://reviews.llvm.org/D100267
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp19
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h3
-rw-r--r--lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test13
3 files changed, 34 insertions, 1 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index f81e2ac..aa5b676 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -265,7 +265,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
m_waiting_for_attach(false), m_destroy_tried_resuming(false),
m_command_sp(), m_breakpoint_pc_offset(0),
m_initial_tid(LLDB_INVALID_THREAD_ID), m_replay_mode(false),
- m_allow_flash_writes(false), m_erased_flash_ranges() {
+ m_allow_flash_writes(false), m_erased_flash_ranges(),
+ m_vfork_in_progress(false) {
m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
"async thread should exit");
m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
@@ -5534,6 +5535,13 @@ void ProcessGDBRemote::DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ assert(!m_vfork_in_progress);
+ m_vfork_in_progress = true;
+
+ // Disable all software breakpoints for the duration of vfork.
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
+ DidForkSwitchSoftwareBreakpoints(false);
+
LLDB_LOG(log, "Detaching forked child {0}", child_pid);
Status error = m_gdb_comm.Detach(false, child_pid);
if (error.Fail()) {
@@ -5543,3 +5551,12 @@ void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
return;
}
}
+
+void ProcessGDBRemote::DidVForkDone() {
+ assert(m_vfork_in_progress);
+ m_vfork_in_progress = false;
+
+ // Reenable all software breakpoints that were enabled before vfork.
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
+ DidForkSwitchSoftwareBreakpoints(true);
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 70b3ca1..ae5fce1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -232,6 +232,7 @@ public:
void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override;
void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override;
+ void DidVForkDone() override;
protected:
friend class ThreadGDBRemote;
@@ -296,6 +297,8 @@ protected:
using FlashRange = FlashRangeVector::Entry;
FlashRangeVector m_erased_flash_ranges;
+ bool m_vfork_in_progress;
+
// Accessors
bool IsRunning(lldb::StateType state) {
return state == lldb::eStateRunning || IsStepping(state);
diff --git a/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test b/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test
new file mode 100644
index 0000000..f158d1a
--- /dev/null
+++ b/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test
@@ -0,0 +1,13 @@
+# REQUIRES: native
+# UNSUPPORTED: system-darwin
+# UNSUPPORTED: system-windows
+# RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_FORK=vfork -o %t
+# RUN: %lldb -b -s %s %t | FileCheck %s
+b parent_func
+b child_func
+process launch
+# CHECK-NOT: function run in parent
+# CHECK: stop reason = breakpoint
+continue
+# CHECK: function run in parent
+# CHECK: child exited: 0