mgorny updated this revision to Diff 369676.
mgorny added a comment.
Rebased
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D100263/new/
https://reviews.llvm.org/D100263
Files:
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py
lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test
lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test
Index: lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test
@@ -0,0 +1,12 @@
+# REQUIRES: native
+# UNSUPPORTED: system-windows
+# RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_FORK=fork -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
Index: lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test
@@ -0,0 +1,13 @@
+# 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
+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
Index: lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py
===================================================================
--- lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py
+++ lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py
@@ -147,7 +147,12 @@
if packet == "s":
return self.haltReason()
if packet[0] == "H":
- return self.selectThread(packet[1], int(packet[2:], 16))
+ tid = packet[2:]
+ if "." in tid:
+ assert tid.startswith("p")
+ # TODO: do we want to do anything with PID?
+ tid = tid.split(".", 1)[1]
+ return self.selectThread(packet[1], int(tid, 16))
if packet[0:6] == "qXfer:":
obj, read, annex, location = packet[6:].split(":")
offset, length = [int(x, 16) for x in location.split(',')]
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -462,6 +462,9 @@
ProcessGDBRemote(const ProcessGDBRemote &) = delete;
const ProcessGDBRemote &operator=(const ProcessGDBRemote &) = delete;
+
+ // fork helpers
+ void DidForkSwitchSoftwareBreakpoints(bool enable);
};
} // namespace process_gdb_remote
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -5485,16 +5485,49 @@
return m_command_sp.get();
}
+void ProcessGDBRemote::DidForkSwitchSoftwareBreakpoints(bool enable) {
+ GetBreakpointSiteList().ForEach([this, enable](BreakpointSite *bp_site) {
+ if (bp_site->IsEnabled() &&
+ (bp_site->GetType() == BreakpointSite::eSoftware ||
+ bp_site->GetType() == BreakpointSite::eExternal)) {
+ m_gdb_comm.SendGDBStoppointTypePacket(
+ eBreakpointSoftware, enable, bp_site->GetLoadAddress(),
+ bp_site->GetTrapOpcodeMaxByteSize(), GetInterruptTimeout());
+ }
+ });
+}
+
void ProcessGDBRemote::DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ lldb::pid_t parent_pid = m_gdb_comm.GetCurrentProcessID();
+ // Any valid TID will suffice, thread-relevant actions will set a proper TID
+ // anyway.
+ lldb::tid_t parent_tid = m_thread_ids.front();
+
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) {
+ // Switch to the new process to clear breakpoints there.
+ if (!m_gdb_comm.SetCurrentThread(child_tid, child_pid)) {
+ LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to set pid/tid");
+ return;
+ }
+
+ // Disable all software breakpoints in the forked process.
+ DidForkSwitchSoftwareBreakpoints(false);
+
+ // Reset gdb-remote to the original process.
+ if (!m_gdb_comm.SetCurrentThread(parent_tid, parent_pid)) {
+ LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to reset pid/tid");
+ return;
+ }
+ }
+
LLDB_LOG(log, "Detaching forked child {0}", child_pid);
Status error = m_gdb_comm.Detach(false, child_pid);
if (error.Fail()) {
- LLDB_LOG(log,
- "ProcessGDBRemote::DidFork() detach packet send failed: {0}",
- error.AsCString() ? error.AsCString() : "<unknown error>");
- return;
+ LLDB_LOG(log, "ProcessGDBRemote::DidFork() detach packet send failed: {0}",
+ error.AsCString() ? error.AsCString() : "<unknown error>");
+ return;
}
}
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits