augusto2112 created this revision.
augusto2112 added reviewers: jingham, jasonmolenda, clayborg.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D100500

Files:
  lldb/include/lldb/Core/Communication.h
  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/ProcessGDBRemote.cpp
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td

Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
@@ -17,4 +17,8 @@
     Global,
     DefaultFalse,
     Desc<"Specify if the server should use 'g' packets to read registers.">;
+  def PacketDelayMultiplier: Property<"packet-delay-multiplier", "UInt64">,
+    Global,
+    DefaultUnsignedValue<0>,
+    Desc<"If greater than 0, sleep for packet-delay-multiplier * packet size nanoseconds for every packet sent or received.">;
 }
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
@@ -164,6 +164,12 @@
     const uint32_t idx = ePropertyUseGPacketForReading;
     return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
   }
+
+  uint64_t GetPacketDelayMultiplier() const {
+    const uint32_t idx = ePropertyPacketDelayMultiplier;
+    return m_collection_sp->GetPropertyAtIndexAsUInt64(
+        nullptr, idx, g_processgdbremote_properties[idx].default_uint_value);
+  }
 };
 
 typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
@@ -252,6 +258,8 @@
 ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
                                    ListenerSP listener_sp)
     : Process(target_sp, listener_sp),
+      m_gdb_comm(std::chrono::nanoseconds(
+          GetGlobalPluginProperties()->GetPacketDelayMultiplier())),
       m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(),
       m_register_info_sp(nullptr),
       m_async_broadcaster(nullptr, "lldb.process.gdb-remote.async-broadcaster"),
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -51,7 +51,8 @@
 
 class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
 public:
-  GDBRemoteCommunicationClient();
+  GDBRemoteCommunicationClient(std::chrono::nanoseconds delay_multiplier =
+                                   std::chrono::nanoseconds::zero());
 
   ~GDBRemoteCommunicationClient() override;
 
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -53,8 +53,10 @@
 }
 
 // GDBRemoteCommunicationClient constructor
-GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
-    : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
+GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(
+    std::chrono::nanoseconds delay_multiplier)
+    : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet",
+                          delay_multiplier),
       m_supports_not_sending_acks(eLazyBoolCalculate),
       m_supports_thread_suffix(eLazyBoolCalculate),
       m_supports_threads_in_stop_reply(eLazyBoolCalculate),
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
@@ -95,7 +95,9 @@
     bool m_timeout_modified;
   };
 
-  GDBRemoteCommunication(const char *comm_name, const char *listener_name);
+  GDBRemoteCommunication(const char *comm_name, const char *listener_name,
+                         std::chrono::nanoseconds delay_multiplier =
+                             std::chrono::nanoseconds::zero());
 
   ~GDBRemoteCommunication() override;
 
@@ -156,6 +158,13 @@
                       // a single process
 
   CompressionType m_compression_type;
+  std::chrono::nanoseconds m_delay_multiplier;
+
+  size_t Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout,
+              lldb::ConnectionStatus &status, Status *error_ptr) override;
+
+  size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus &status,
+               Status *error_ptr) override;
 
   PacketResult SendPacketNoLock(llvm::StringRef payload);
   PacketResult SendRawPacketNoLock(llvm::StringRef payload,
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
@@ -60,7 +60,8 @@
 
 // GDBRemoteCommunication constructor
 GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
-                                               const char *listener_name)
+                                               const char *listener_name,
+                                               std::chrono::nanoseconds delay_multiplier)
     : Communication(comm_name),
 #ifdef LLDB_CONFIGURATION_DEBUG
       m_packet_timeout(1000),
@@ -69,7 +70,7 @@
 #endif
       m_echo_number(0), m_supports_qEcho(eLazyBoolCalculate), m_history(512),
       m_send_acks(true), m_compression_type(CompressionType::None),
-      m_listen_url() {
+      m_delay_multiplier(delay_multiplier), m_listen_url() {
 }
 
 // Destructor
@@ -98,6 +99,22 @@
   return checksum & 255;
 }
 
+size_t GDBRemoteCommunication::Read(void *dst, size_t dst_len,
+                                    const Timeout<std::micro> &timeout,
+                                    lldb::ConnectionStatus &status,
+                                    Status *error_ptr) {
+  size_t size = Communication::Read(dst, dst_len, timeout, status, error_ptr);
+  std::this_thread::sleep_for(m_delay_multiplier * size);
+  return size;
+}
+
+size_t GDBRemoteCommunication::Write(const void *src, size_t src_len,
+                            ConnectionStatus &status, Status *error_ptr) {
+  size_t size = Communication::Write(src, src_len, status, error_ptr);
+  std::this_thread::sleep_for(m_delay_multiplier * size);
+  return size;
+
+}
 size_t GDBRemoteCommunication::SendAck() {
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
   ConnectionStatus status = eConnectionStatusSuccess;
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
@@ -31,7 +31,9 @@
     virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data) = 0;
   };
 
-  GDBRemoteClientBase(const char *comm_name, const char *listener_name);
+  GDBRemoteClientBase(const char *comm_name, const char *listener_name,
+                      std::chrono::nanoseconds delay_multiplier =
+                          std::chrono::nanoseconds::zero());
 
   bool SendAsyncSignal(int signo);
 
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
@@ -28,10 +28,11 @@
 
 GDBRemoteClientBase::ContinueDelegate::~ContinueDelegate() = default;
 
-GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name,
-                                         const char *listener_name)
-    : GDBRemoteCommunication(comm_name, listener_name), m_async_count(0),
-      m_is_running(false), m_should_stop(false) {}
+GDBRemoteClientBase::GDBRemoteClientBase(
+    const char *comm_name, const char *listener_name,
+    std::chrono::nanoseconds delay_multiplier)
+    : GDBRemoteCommunication(comm_name, listener_name, delay_multiplier),
+      m_async_count(0), m_is_running(false), m_should_stop(false) {}
 
 StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
     ContinueDelegate &delegate, const UnixSignals &signals,
Index: lldb/include/lldb/Core/Communication.h
===================================================================
--- lldb/include/lldb/Core/Communication.h
+++ lldb/include/lldb/Core/Communication.h
@@ -188,8 +188,9 @@
   ///     The number of bytes actually read.
   ///
   /// \see size_t Connection::Read (void *, size_t);
-  size_t Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout,
-              lldb::ConnectionStatus &status, Status *error_ptr);
+  virtual size_t Read(void *dst, size_t dst_len,
+                      const Timeout<std::micro> &timeout,
+                      lldb::ConnectionStatus &status, Status *error_ptr);
 
   /// The actual write function that attempts to write to the communications
   /// protocol.
@@ -206,8 +207,8 @@
   ///
   /// \return
   ///     The number of bytes actually Written.
-  size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus &status,
-               Status *error_ptr);
+  virtual size_t Write(const void *src, size_t src_len,
+                       lldb::ConnectionStatus &status, Status *error_ptr);
 
   /// Sets the connection that it to be used by this class.
   ///
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to