================ @@ -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))) { ---------------- jimingham wrote:
I try to avoid any hard coded timeouts, mostly because it's easy to lose track of where timeouts are occurring. If you make a constant with a good name and use that they are easier to find. https://github.com/llvm/llvm-project/pull/99736 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits