[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

Robert O'Callahan via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 22 14:40:43 PDT 2024


================
@@ -1395,6 +1395,94 @@ Status ProcessGDBRemote::DoResume() {
   return error;
 }
 
+Status ProcessGDBRemote::DoResumeReverse() {
+  Status error;
+  Log *log = GetLog(GDBRLog::Process);
+  LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse()");
+
+  ListenerSP listener_sp(
+      Listener::MakeListener("gdb-remote.resume-packet-sent"));
+  if (listener_sp->StartListeningForEvents(
+          &m_gdb_comm, GDBRemoteClientBase::eBroadcastBitRunPacketSent)) {
+    listener_sp->StartListeningForEvents(
+        &m_async_broadcaster,
+        ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
+
+    const size_t num_threads = GetThreadList().GetSize();
+
+    StreamString continue_packet;
+
+    // Number of threads continuing with "C", i.e. continuing with a signal to deliver.
+    const size_t num_continue_C_tids = m_continue_C_tids.size();
+    // Number of threads continuing with "s", i.e. single-stepping.
+    const size_t num_continue_s_tids = m_continue_s_tids.size();
+    // Number of threads continuing with "S", i.e. single-stepping with a signal to deliver.
+    const size_t num_continue_S_tids = m_continue_S_tids.size();
+    // We can only `bc` to reverse-continue all threads,
+    // or `bs` to reverse-step the current thread (which may also
+    // reverse-continue other threads by some amount).
+    // These packets do not support delivering signals.
+    if (num_continue_C_tids > 0 || num_continue_S_tids > 0) {
+      error.SetErrorString("can't deliver signals while running in reverse");
+      LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: Signals not supported");
+      return error;
+    }
+
+    if (num_continue_s_tids > 0) {
+      if (num_continue_s_tids > 1) {
+        error.SetErrorString("can't step multiple threads while reverse-stepping");
+        LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: can't step multiple threads");
+        return error;
+      }
+
+      if (!m_gdb_comm.GetReverseStepSupported()) {
+        error.SetErrorString("target does not support reverse-stepping");
+        LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: target does not support reverse-stepping");
+        return error;
+      }
+
+      m_gdb_comm.SetCurrentThreadForRun(m_continue_s_tids.front());
+      continue_packet.PutCString("bs");
+    } else {
+      if (!m_gdb_comm.GetReverseContinueSupported()) {
+        error.SetErrorString("target does not support reverse-continue");
+        LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: target does not support reverse-continue");
+        return error;
+      }
+
+      // All threads continue whether requested or not ---
+      // we can't change how threads ran in the past.
+      continue_packet.PutCString("bc");
+    }
+
+    EventSP event_sp;
+    if (!m_async_thread.IsJoinable()) {
+      error.SetErrorString("Trying to resume but the async thread is dead.");
+      LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: Trying to resume but the "
+                     "async thread is dead.");
+      return error;
+    }
+
+    auto data_sp =
+        std::make_shared<EventDataBytes>(continue_packet.GetString());
+    m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue, data_sp);
+
+    if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) {
----------------
rocallahan wrote:

This was copied from `ProcessGDBRemote::DoResume()`. I can refactor that.

https://github.com/llvm/llvm-project/pull/99736


More information about the lldb-commits mailing list