[Lldb-commits] [PATCH] D135031: [lldb] [llgs] Move client-server communication into a separate thread (WIP)

2022-10-02 Thread Michał Górny via Phabricator via lldb-commits
mgorny created this revision.
mgorny added reviewers: krytarowski, emaste, labath, jingham.
Herald added a subscriber: arichardson.
Herald added a project: All.
mgorny requested review of this revision.

Perform all the communication between client and server in a dedicated
thread that's started after establishing the connection.  The thread
uses a MainLoop instance to read all incoming packets into a queue,
and handle asynchronous requests from the client via
the AddPendingCallback() API.

Using a dedicated thread will make it possible to continuously read
asynchronous notifications from running processes while permitting
the plugin to simultaneously handle synchronous requests in multiprocess
mode.

Sponsored by: The FreeBSD Foundation

TODO:

- implement complete error handling
- implement timeouts


https://reviews.llvm.org/D135031

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

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
@@ -886,6 +886,11 @@
 return error;
   }
 
+  llvm::Error thread_error = m_gdb_comm.StartThread();
+  if (thread_error) {
+m_gdb_comm.Disconnect();
+return Status(std::move(thread_error));
+  }
   // We always seem to be able to open a connection to a local port so we need
   // to make sure we can then send data to it. If we can't then we aren't
   // actually connected to anything, so try and do the handshake with the
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
@@ -11,7 +11,11 @@
 
 #include "GDBRemoteCommunication.h"
 
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/MainLoop.h"
+
 #include 
+#include 
 
 namespace lldb_private {
 namespace process_gdb_remote {
@@ -22,6 +26,9 @@
 
   enum {
 eBroadcastBitRunPacketSent = (1u << 0),
+eBroadcastBitCommDone = (1u << 1),
+eBroadcastBitCommThreadExited = (1u << 2),
+eBroadcastBitCommPacketRecv = (1u << 3),
   };
 
   struct ContinueDelegate {
@@ -116,9 +123,23 @@
 return m_comm;
   }
 
+  llvm::Error StartThread();
+  void StopThread();
+
 protected:
   GDBRemoteCommunication m_comm;
 
+  HostThread m_comm_thread;
+  bool m_comm_thread_exited;
+  std::unique_ptr m_comm_loop_up;
+  std::deque m_comm_sync_packet_queue;
+
+  void CommThreadReadHandler(MainLoopBase );
+  lldb::thread_result_t CommThread();
+
+  bool RequestComm(const MainLoop::Callback _callback,
+   const MainLoop::Callback _callback);
+
   PacketResult
   SendPacketAndWaitForResponseNoLock(llvm::StringRef payload,
  StringExtractorGDBRemote );
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
@@ -10,7 +10,10 @@
 
 #include "llvm/ADT/StringExtras.h"
 
+#include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/Connection.h"
+#include "lldb/Utility/Event.h"
 #include "lldb/Utility/LLDBAssert.h"
 
 #include "ProcessGDBRemoteLog.h"
@@ -237,29 +240,50 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
 llvm::StringRef payload, StringExtractorGDBRemote ) {
-  PacketResult packet_result = SendPacketNoLock(payload);
-  if (packet_result != PacketResult::Success)
-return packet_result;
-
+  PacketResult packet_result;
   const size_t max_response_retries = 3;
-  for (size_t i = 0; i < max_response_retries; ++i) {
-packet_result = ReadPacket(response, m_comm.GetPacketTimeout(), true);
-// Make sure we received a response
-if (packet_result != PacketResult::Success)
-  return packet_result;
-// Make sure our response is valid for the payload that was sent
-if (response.ValidateResponse())
-  return packet_result;
-// Response says it wasn't valid
-Log *log = GetLog(GDBRLog::Packets);
-LLDB_LOGF(
-log,
-"error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
-int(payload.size()), payload.data(), response.GetStringRef().data(),
-(i == (max_response_retries - 1))
-? "using invalid response and giving up"
-: "ignoring response and waiting for another");
-  }
+  size_t response_retry = 0;
+
+  // TODO: timeout
+  if (!RequestComm(
+  [this, payload, _result](MainLoopBase &) {
+

[Lldb-commits] [PATCH] D135030: [lldb] [gdb-remote] Abstract sending ^c packet into SendCtrlC() method

2022-10-02 Thread Michał Górny via Phabricator via lldb-commits
mgorny created this revision.
mgorny added reviewers: labath, emaste, jingham, krytarowski.
Herald added a subscriber: arichardson.
Herald added a project: All.
mgorny requested review of this revision.

Abstract sending ^c packet into a dedicated
GDBRemoteClientBase::SendCtrlC() method. This makes it possible to avoid
exposing the complete Write() method in the API.

Sponsored by: The FreeBSD Foundation


https://reviews.llvm.org/D135030

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h


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
@@ -106,8 +106,7 @@
 
   size_t SendAck();
 
-  size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus ,
-   Status *error_ptr);
+  bool SendCtrlC();
 
   bool IsConnected() const;
 
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
@@ -374,10 +374,7 @@
 if (m_comm.m_async_count == 1) {
   // The sender has sent the continue packet and we are the first async
   // packet. Let's interrupt it.
-  const char ctrl_c = '\x03';
-  ConnectionStatus status = eConnectionStatusSuccess;
-  size_t bytes_written = m_comm.Write(_c, 1, status, nullptr);
-  if (bytes_written == 0) {
+  if (!m_comm.SendCtrlC()) {
 --m_comm.m_async_count;
 LLDB_LOGF(log, "GDBRemoteClientBase::Lock::Lock failed to send "
"interrupt packet");
@@ -417,9 +414,11 @@
 
 size_t GDBRemoteClientBase::SendAck() { return m_comm.SendAck(); }
 
-size_t GDBRemoteClientBase::Write(const void *src, size_t src_len,
-  ConnectionStatus , Status *error_ptr) 
{
-  return m_comm.Write(src, src_len, status, error_ptr);
+bool GDBRemoteClientBase::SendCtrlC() {
+  const char ctrl_c = '\x03';
+  ConnectionStatus status = eConnectionStatusSuccess;
+  size_t bytes_written = m_comm.Write(_c, 1, status, nullptr);
+  return bytes_written != 0;
 }
 
 bool GDBRemoteClientBase::IsConnected() const { return m_comm.IsConnected(); }


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
@@ -106,8 +106,7 @@
 
   size_t SendAck();
 
-  size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus ,
-   Status *error_ptr);
+  bool SendCtrlC();
 
   bool IsConnected() const;
 
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
@@ -374,10 +374,7 @@
 if (m_comm.m_async_count == 1) {
   // The sender has sent the continue packet and we are the first async
   // packet. Let's interrupt it.
-  const char ctrl_c = '\x03';
-  ConnectionStatus status = eConnectionStatusSuccess;
-  size_t bytes_written = m_comm.Write(_c, 1, status, nullptr);
-  if (bytes_written == 0) {
+  if (!m_comm.SendCtrlC()) {
 --m_comm.m_async_count;
 LLDB_LOGF(log, "GDBRemoteClientBase::Lock::Lock failed to send "
"interrupt packet");
@@ -417,9 +414,11 @@
 
 size_t GDBRemoteClientBase::SendAck() { return m_comm.SendAck(); }
 
-size_t GDBRemoteClientBase::Write(const void *src, size_t src_len,
-  ConnectionStatus , Status *error_ptr) {
-  return m_comm.Write(src, src_len, status, error_ptr);
+bool GDBRemoteClientBase::SendCtrlC() {
+  const char ctrl_c = '\x03';
+  ConnectionStatus status = eConnectionStatusSuccess;
+  size_t bytes_written = m_comm.Write(_c, 1, status, nullptr);
+  return bytes_written != 0;
 }
 
 bool GDBRemoteClientBase::IsConnected() const { return m_comm.IsConnected(); }
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D135029: [lldb] [gdb-remote] Isolate ClientBase from Communication

2022-10-02 Thread Michał Górny via Phabricator via lldb-commits
mgorny created this revision.
mgorny added reviewers: labath, jingham, krytarowski, emaste.
Herald added a subscriber: arichardson.
Herald added a project: All.
mgorny requested review of this revision.

Introduce an isolation layer between GDBRemoteClientBase
and GDBRemoteCommunication.  This makes it possible to replace
the public packet reading/writing API with wrappers that will make
threaded access possible in the future.

Sponsored by: The FreeBSD Foundation


https://reviews.llvm.org/D135029

Files:
  lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
  lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
  lldb/unittests/tools/lldb-server/tests/TestClient.cpp

Index: lldb/unittests/tools/lldb-server/tests/TestClient.cpp
===
--- lldb/unittests/tools/lldb-server/tests/TestClient.cpp
+++ lldb/unittests/tools/lldb-server/tests/TestClient.cpp
@@ -31,8 +31,8 @@
 #endif
 
 TestClient::TestClient(std::unique_ptr Conn) {
-  SetConnection(std::move(Conn));
-  SetPacketTimeout(std::chrono::seconds(10));
+  GetCommunication().SetConnection(std::move(Conn));
+  GetCommunication().SetPacketTimeout(std::chrono::seconds(10));
 }
 
 TestClient::~TestClient() {
@@ -50,7 +50,7 @@
   if (Error E = SendMessage("QStartNoAckMode"))
 return E;
 
-  m_send_acks = false;
+  GetCommunication().DisableSendingAcks();
   return Error::success();
 }
 
@@ -268,7 +268,8 @@
   m_stop_reply = std::move(*StopReplyOr);
   if (!isa(m_stop_reply)) {
 StringExtractorGDBRemote R;
-PacketResult result = ReadPacket(R, GetPacketTimeout(), false);
+PacketResult result =
+ReadPacket(R, GetCommunication().GetPacketTimeout(), false);
 if (result != PacketResult::ErrorDisconnected) {
   return make_error(
   formatv("Expected connection close after sending {0}. Got {1}/{2} "
Index: lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
===
--- lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -29,7 +29,9 @@
 typedef GDBRemoteCommunication::PacketResult PacketResult;
 
 struct TestClient : public GDBRemoteCommunicationClient {
-  TestClient() { m_send_acks = false; }
+  TestClient() {
+GetCommunication().DisableSendingAcks();
+  }
 };
 
 void Handle_QThreadSuffixSupported(MockServer , bool supported) {
@@ -62,7 +64,8 @@
 class GDBRemoteCommunicationClientTest : public GDBRemoteTest {
 public:
   void SetUp() override {
-ASSERT_THAT_ERROR(GDBRemoteCommunication::ConnectLocally(client, server),
+ASSERT_THAT_ERROR(GDBRemoteCommunication::ConnectLocally(
+  client.GetCommunication(), server),
   llvm::Succeeded());
   }
 
Index: lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
===
--- lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
+++ lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
@@ -40,14 +40,15 @@
 
 struct TestClient : public GDBRemoteClientBase {
   TestClient() : GDBRemoteClientBase("test.client") {
-m_send_acks = false;
+GetCommunication().DisableSendingAcks();
   }
 };
 
 class GDBRemoteClientBaseTest : public GDBRemoteTest {
 public:
   void SetUp() override {
-ASSERT_THAT_ERROR(GDBRemoteCommunication::ConnectLocally(client, server),
+ASSERT_THAT_ERROR(GDBRemoteCommunication::ConnectLocally(
+  client.GetCommunication(), server),
   llvm::Succeeded());
 ASSERT_EQ(TestClient::eBroadcastBitRunPacketSent,
   listener_sp->StartListeningForEvents(
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
@@ -109,7 +109,10 @@
 return;
   }
   StreamFile stream(std::move(file.get()));
-  ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(stream);
+  ((ProcessGDBRemote *)p)
+  ->GetGDBRemote()
+  .GetCommunication()
+  .DumpHistory(stream);
 }
 } // namespace lldb
 
@@ -281,7 +284,8 @@
   

[Lldb-commits] [PATCH] D135028: [lldb] [gdb-remote] Move ReadPacketWithOutputSupport() to client

2022-10-02 Thread Michał Górny via Phabricator via lldb-commits
mgorny created this revision.
mgorny added reviewers: labath, emaste, krytarowski, jingham.
Herald added a project: All.
mgorny requested review of this revision.

Move ReadPacketWithOutputSupport() from GDBRemoteCommunication
to GDBRemoteClientBase.  This function is client-specific and moving
it there simplifies followup patches that split communication into
separate thread.


https://reviews.llvm.org/D135028

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h


Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -190,11 +190,6 @@
   PacketResult ReadPacket(StringExtractorGDBRemote ,
   Timeout timeout, bool sync_on_timeout);
 
-  PacketResult ReadPacketWithOutputSupport(
-  StringExtractorGDBRemote , Timeout timeout,
-  bool sync_on_timeout,
-  llvm::function_ref output_callback);
-
   PacketResult WaitForPacketNoLock(StringExtractorGDBRemote ,
Timeout timeout,
bool sync_on_timeout);
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -220,23 +220,6 @@
   return result;
 }
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::ReadPacketWithOutputSupport(
-StringExtractorGDBRemote , Timeout timeout,
-bool sync_on_timeout,
-llvm::function_ref output_callback) {
-  auto result = ReadPacket(response, timeout, sync_on_timeout);
-  while (result == PacketResult::Success && response.IsNormalResponse() &&
- response.PeekChar() == 'O') {
-response.GetChar();
-std::string output;
-if (response.GetHexByteString(output))
-  output_callback(output);
-result = ReadPacket(response, timeout, sync_on_timeout);
-  }
-  return result;
-}
-
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunication::ReadPacket(StringExtractorGDBRemote ,
Timeout timeout,
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
@@ -58,6 +58,11 @@
   llvm::StringRef payload, StringExtractorGDBRemote ,
   std::chrono::seconds interrupt_timeout = std::chrono::seconds(0));
 
+  PacketResult ReadPacketWithOutputSupport(
+  StringExtractorGDBRemote , Timeout timeout,
+  bool sync_on_timeout,
+  llvm::function_ref output_callback);
+
   PacketResult SendPacketAndReceiveResponseWithOutputSupport(
   llvm::StringRef payload, StringExtractorGDBRemote ,
   std::chrono::seconds interrupt_timeout,
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
@@ -194,6 +194,23 @@
   return SendPacketAndWaitForResponseNoLock(payload, response);
 }
 
+GDBRemoteCommunication::PacketResult
+GDBRemoteClientBase::ReadPacketWithOutputSupport(
+StringExtractorGDBRemote , Timeout timeout,
+bool sync_on_timeout,
+llvm::function_ref output_callback) {
+  auto result = ReadPacket(response, timeout, sync_on_timeout);
+  while (result == PacketResult::Success && response.IsNormalResponse() &&
+ response.PeekChar() == 'O') {
+response.GetChar();
+std::string output;
+if (response.GetHexByteString(output))
+  output_callback(output);
+result = ReadPacket(response, timeout, sync_on_timeout);
+  }
+  return result;
+}
+
 GDBRemoteCommunication::PacketResult
 GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
 llvm::StringRef payload, StringExtractorGDBRemote ,


Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -190,11 +190,6 @@
   PacketResult ReadPacket(StringExtractorGDBRemote ,
   Timeout timeout, bool sync_on_timeout);
 
-  PacketResult ReadPacketWithOutputSupport(
-  StringExtractorGDBRemote , Timeout timeout,
-  bool sync_on_timeout,
-  

[Lldb-commits] [PATCH] D134133: WIP: [lldb][COFF] Enhance symtab loading of symbol and export tables

2022-10-02 Thread Alvin Wong via Phabricator via lldb-commits
alvinhochun abandoned this revision.
alvinhochun added a comment.

Handled in separate changes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134133/new/

https://reviews.llvm.org/D134133

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits