Skip to content

Commit 199344d

Browse files
committed
[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
1 parent ff78001 commit 199344d

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
265265
m_waiting_for_attach(false), m_destroy_tried_resuming(false),
266266
m_command_sp(), m_breakpoint_pc_offset(0),
267267
m_initial_tid(LLDB_INVALID_THREAD_ID), m_replay_mode(false),
268-
m_allow_flash_writes(false), m_erased_flash_ranges() {
268+
m_allow_flash_writes(false), m_erased_flash_ranges(),
269+
m_vfork_in_progress(false) {
269270
m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
270271
"async thread should exit");
271272
m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
@@ -5534,6 +5535,13 @@ void ProcessGDBRemote::DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
55345535
void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
55355536
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
55365537

5538+
assert(!m_vfork_in_progress);
5539+
m_vfork_in_progress = true;
5540+
5541+
// Disable all software breakpoints for the duration of vfork.
5542+
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
5543+
DidForkSwitchSoftwareBreakpoints(false);
5544+
55375545
LLDB_LOG(log, "Detaching forked child {0}", child_pid);
55385546
Status error = m_gdb_comm.Detach(false, child_pid);
55395547
if (error.Fail()) {
@@ -5543,3 +5551,12 @@ void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
55435551
return;
55445552
}
55455553
}
5554+
5555+
void ProcessGDBRemote::DidVForkDone() {
5556+
assert(m_vfork_in_progress);
5557+
m_vfork_in_progress = false;
5558+
5559+
// Reenable all software breakpoints that were enabled before vfork.
5560+
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
5561+
DidForkSwitchSoftwareBreakpoints(true);
5562+
}

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ class ProcessGDBRemote : public Process,
232232

233233
void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override;
234234
void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override;
235+
void DidVForkDone() override;
235236

236237
protected:
237238
friend class ThreadGDBRemote;
@@ -296,6 +297,8 @@ class ProcessGDBRemote : public Process,
296297
using FlashRange = FlashRangeVector::Entry;
297298
FlashRangeVector m_erased_flash_ranges;
298299

300+
bool m_vfork_in_progress;
301+
299302
// Accessors
300303
bool IsRunning(lldb::StateType state) {
301304
return state == lldb::eStateRunning || IsStepping(state);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# REQUIRES: native
2+
# UNSUPPORTED: system-darwin
3+
# UNSUPPORTED: system-windows
4+
# RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_FORK=vfork -o %t
5+
# RUN: %lldb -b -s %s %t | FileCheck %s
6+
b parent_func
7+
b child_func
8+
process launch
9+
# CHECK-NOT: function run in parent
10+
# CHECK: stop reason = breakpoint
11+
continue
12+
# CHECK: function run in parent
13+
# CHECK: child exited: 0

0 commit comments

Comments
 (0)