mgorny created this revision. mgorny added reviewers: labath, krytarowski, emaste, jingham. Herald added a subscriber: arichardson. Herald added a project: All. mgorny requested review of this revision.
Introduce the initial support for handling multiple ContinueDelegates in GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(). This is the first step towards moving to a shared asynchronous thread serving multiple ProcessGDBRemote instances. The final goal is that every stop response will be passed through all ContinueDelegates, and every delegate will decide whether it is applicable to its process. The additional `handled` parameter is used to indicate that the correct delegate has been found and no further delegates need to be invoked. The next step is going to involve decoupling the async thread from ProcessGDBRemote itself, and moving all the logic responsible for updating the process status into ContinueDelegate API. Sponsored by: The FreeBSD Foundation https://reviews.llvm.org/D131837 Files: lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
Index: lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp =================================================================== --- lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp +++ lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp @@ -29,12 +29,23 @@ unsigned stop_reply_called = 0; std::vector<std::string> structured_data_packets; - void HandleAsyncStdout(llvm::StringRef out) override { output += out; } - void HandleAsyncMisc(llvm::StringRef data) override { misc_data += data; } - void HandleStopReply() override { ++stop_reply_called; } + void HandleAsyncStdout(llvm::StringRef out, bool &handled) override { + output += out; + handled = true; + } + void HandleAsyncMisc(llvm::StringRef data, bool &handled) override { + misc_data += data; + handled = true; + } + void HandleStopReply(bool &handled) override { + ++stop_reply_called; + handled = true; + } - void HandleAsyncStructuredDataPacket(llvm::StringRef data) override { + void HandleAsyncStructuredDataPacket(llvm::StringRef data, + bool &handled) override { structured_data_packets.push_back(std::string(data)); + handled = true; } }; @@ -63,9 +74,8 @@ ListenerSP listener_sp = Listener::MakeListener("listener"); StateType SendCPacket(StringExtractorGDBRemote &response) { - return client.SendContinuePacketAndWaitForResponse(delegate, LinuxSignals(), - "c", g_timeout, - response); + return client.SendContinuePacketAndWaitForResponse( + {&delegate}, LinuxSignals(), "c", g_timeout, response); } void WaitForRunEvent() { 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 @@ -425,10 +425,11 @@ lldb::user_id_t break_loc_id); // ContinueDelegate interface - void HandleAsyncStdout(llvm::StringRef out) override; - void HandleAsyncMisc(llvm::StringRef data) override; - void HandleStopReply() override; - void HandleAsyncStructuredDataPacket(llvm::StringRef data) override; + void HandleAsyncStdout(llvm::StringRef out, bool &handled) override; + void HandleAsyncMisc(llvm::StringRef data, bool &handled) override; + void HandleStopReply(bool &handled) override; + void HandleAsyncStructuredDataPacket(llvm::StringRef data, + bool &handled) override; void SetThreadPc(const lldb::ThreadSP &thread_sp, uint64_t index); using ModuleCacheKey = std::pair<std::string, std::string>; 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 @@ -3484,7 +3484,7 @@ StateType stop_state = GetGDBRemote().SendContinuePacketAndWaitForResponse( - *this, *GetUnixSignals(), + {this}, *GetUnixSignals(), llvm::StringRef(continue_cstr, continue_cstr_len), GetInterruptTimeout(), response); @@ -4642,14 +4642,15 @@ m_gdb_comm.ServeSymbolLookups(this); } -void ProcessGDBRemote::HandleAsyncStdout(llvm::StringRef out) { +void ProcessGDBRemote::HandleAsyncStdout(llvm::StringRef out, bool &handled) { AppendSTDOUT(out.data(), out.size()); + handled = true; } static const char *end_delimiter = "--end--;"; static const int end_delimiter_len = 8; -void ProcessGDBRemote::HandleAsyncMisc(llvm::StringRef data) { +void ProcessGDBRemote::HandleAsyncMisc(llvm::StringRef data, bool &handled) { std::string input = data.str(); // '1' to move beyond 'A' if (m_partial_profile_data.length() > 0) { m_partial_profile_data.append(input); @@ -4672,6 +4673,8 @@ // Last incomplete chunk. m_partial_profile_data = input.substr(pos); } + + handled = true; } std::string ProcessGDBRemote::HarmonizeThreadIdsForProfileData( @@ -4750,7 +4753,8 @@ return output_stream.str(); } -void ProcessGDBRemote::HandleStopReply() { +void ProcessGDBRemote::HandleStopReply(bool &handled) { + handled = true; if (GetStopID() != 0) return; @@ -4854,10 +4858,12 @@ return json_sp; } -void ProcessGDBRemote::HandleAsyncStructuredDataPacket(llvm::StringRef data) { +void ProcessGDBRemote::HandleAsyncStructuredDataPacket(llvm::StringRef data, + bool &handled) { auto structured_data_sp = ParseStructuredDataPacket(data); if (structured_data_sp) RouteAsyncStructuredData(structured_data_sp); + handled = true; } class CommandObjectProcessGDBRemoteSpeedTest : public CommandObjectParsed { Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h =================================================================== --- lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h +++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h @@ -20,15 +20,16 @@ public: struct ContinueDelegate { virtual ~ContinueDelegate(); - virtual void HandleAsyncStdout(llvm::StringRef out) = 0; - virtual void HandleAsyncMisc(llvm::StringRef data) = 0; - virtual void HandleStopReply() = 0; + virtual void HandleAsyncStdout(llvm::StringRef out, bool &handled) = 0; + virtual void HandleAsyncMisc(llvm::StringRef data, bool &handled) = 0; + virtual void HandleStopReply(bool &handled) = 0; /// Process asynchronously-received structured data. /// /// \param[in] data /// The complete data packet, expected to start with JSON-async. - virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data) = 0; + virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data, + bool &handled) = 0; }; GDBRemoteClientBase(const char *comm_name, const char *listener_name); @@ -38,7 +39,7 @@ bool Interrupt(std::chrono::seconds interrupt_timeout); lldb::StateType SendContinuePacketAndWaitForResponse( - ContinueDelegate &delegate, const UnixSignals &signals, + llvm::ArrayRef<ContinueDelegate *> delegates, const UnixSignals &signals, llvm::StringRef payload, std::chrono::seconds interrupt_timeout, StringExtractorGDBRemote &response); Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp +++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp @@ -37,7 +37,7 @@ m_is_running(false), m_should_stop(false) {} StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse( - ContinueDelegate &delegate, const UnixSignals &signals, + llvm::ArrayRef<ContinueDelegate *> delegates, const UnixSignals &signals, llvm::StringRef payload, std::chrono::seconds interrupt_timeout, StringExtractorGDBRemote &response) { Log *log = GetLog(GDBRLog::Process); @@ -113,15 +113,31 @@ case 'O': { std::string inferior_stdout; response.GetHexByteString(inferior_stdout); - delegate.HandleAsyncStdout(inferior_stdout); + for (auto delegate : delegates) { + bool handled = false; + delegate->HandleAsyncStdout(inferior_stdout, handled); + if (handled) + break; + } break; } case 'A': - delegate.HandleAsyncMisc( - llvm::StringRef(response.GetStringRef()).substr(1)); + for (auto delegate : delegates) { + bool handled = false; + delegate->HandleAsyncMisc( + llvm::StringRef(response.GetStringRef()).substr(1), handled); + if (handled) + break; + } break; case 'J': - delegate.HandleAsyncStructuredDataPacket(response.GetStringRef()); + for (auto delegate : delegates) { + bool handled = false; + delegate->HandleAsyncStructuredDataPacket(response.GetStringRef(), + handled); + if (handled) + break; + } break; case 'T': case 'S': @@ -140,7 +156,12 @@ m_continue_packet = 'c'; cont_lock.unlock(); - delegate.HandleStopReply(); + for (auto delegate : delegates) { + bool handled = false; + delegate->HandleStopReply(handled); + if (handled) + break; + } if (should_stop) return eStateStopped;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits