1 //===-- GDBRemoteCommunication.h --------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_GDBRemoteCommunication_h_ 11 #define liblldb_GDBRemoteCommunication_h_ 12 13 // C Includes 14 // C++ Includes 15 #include <list> 16 #include <string> 17 #include <queue> 18 19 // Other libraries and framework includes 20 // Project includes 21 #include "lldb/lldb-public.h" 22 #include "lldb/Core/Communication.h" 23 #include "lldb/Core/Listener.h" 24 #include "lldb/Host/HostThread.h" 25 #include "lldb/Host/Mutex.h" 26 #include "lldb/Host/Predicate.h" 27 #include "lldb/Host/TimeValue.h" 28 29 #include "Utility/StringExtractorGDBRemote.h" 30 31 namespace lldb_private { 32 namespace process_gdb_remote { 33 34 typedef enum 35 { 36 eStoppointInvalid = -1, 37 eBreakpointSoftware = 0, 38 eBreakpointHardware, 39 eWatchpointWrite, 40 eWatchpointRead, 41 eWatchpointReadWrite 42 } GDBStoppointType; 43 44 enum class CompressionType 45 { 46 None = 0, // no compression 47 ZlibDeflate, // zlib's deflate compression scheme, requires zlib or Apple's libcompression 48 LZFSE, // an Apple compression scheme, requires Apple's libcompression 49 LZ4, // lz compression - called "lz4 raw" in libcompression terms, compat with https://code.google.com/p/lz4/ 50 LZMA, // Lempel–Ziv–Markov chain algorithm 51 }; 52 53 class ProcessGDBRemote; 54 55 class GDBRemoteCommunication : public Communication 56 { 57 public: 58 enum 59 { 60 eBroadcastBitRunPacketSent = kLoUserBroadcastBit, 61 eBroadcastBitGdbReadThreadGotNotify = kLoUserBroadcastBit << 1 // Sent when we received a notify packet. 62 }; 63 64 enum class PacketType 65 { 66 Invalid = 0, 67 Standard, 68 Notify 69 }; 70 71 enum class PacketResult 72 { 73 Success = 0, // Success 74 ErrorSendFailed, // Error sending the packet 75 ErrorSendAck, // Didn't get an ack back after sending a packet 76 ErrorReplyFailed, // Error getting the reply 77 ErrorReplyTimeout, // Timed out waiting for reply 78 ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that was sent 79 ErrorReplyAck, // Sending reply ack failed 80 ErrorDisconnected, // We were disconnected 81 ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request 82 }; 83 84 // Class to change the timeout for a given scope and restore it to the original value when the 85 // created ScopedTimeout object got out of scope 86 class ScopedTimeout 87 { 88 public: 89 ScopedTimeout (GDBRemoteCommunication& gdb_comm, uint32_t timeout); 90 ~ScopedTimeout (); 91 92 private: 93 GDBRemoteCommunication& m_gdb_comm; 94 uint32_t m_saved_timeout; 95 }; 96 97 //------------------------------------------------------------------ 98 // Constructors and Destructors 99 //------------------------------------------------------------------ 100 GDBRemoteCommunication(const char *comm_name, 101 const char *listener_name); 102 103 virtual 104 ~GDBRemoteCommunication(); 105 106 PacketResult 107 GetAck (); 108 109 size_t 110 SendAck (); 111 112 size_t 113 SendNack (); 114 115 char 116 CalculcateChecksum (const char *payload, 117 size_t payload_length); 118 119 bool 120 GetSequenceMutex (Mutex::Locker& locker, const char *failure_message = NULL); 121 122 PacketType 123 CheckForPacket (const uint8_t *src, 124 size_t src_len, 125 StringExtractorGDBRemote &packet); 126 bool IsRunning()127 IsRunning() const 128 { 129 return m_public_is_running.GetValue(); 130 } 131 132 bool GetSendAcks()133 GetSendAcks () 134 { 135 return m_send_acks; 136 } 137 138 //------------------------------------------------------------------ 139 // Client and server must implement these pure virtual functions 140 //------------------------------------------------------------------ 141 virtual bool 142 GetThreadSuffixSupported () = 0; 143 144 //------------------------------------------------------------------ 145 // Set the global packet timeout. 146 // 147 // For clients, this is the timeout that gets used when sending 148 // packets and waiting for responses. For servers, this might not 149 // get used, and if it doesn't this should be moved to the 150 // GDBRemoteCommunicationClient. 151 //------------------------------------------------------------------ 152 uint32_t SetPacketTimeout(uint32_t packet_timeout)153 SetPacketTimeout (uint32_t packet_timeout) 154 { 155 const uint32_t old_packet_timeout = m_packet_timeout; 156 m_packet_timeout = packet_timeout; 157 return old_packet_timeout; 158 } 159 160 uint32_t GetPacketTimeoutInMicroSeconds()161 GetPacketTimeoutInMicroSeconds () const 162 { 163 return m_packet_timeout * TimeValue::MicroSecPerSec; 164 } 165 //------------------------------------------------------------------ 166 // Start a debugserver instance on the current host using the 167 // supplied connection URL. 168 //------------------------------------------------------------------ 169 Error 170 StartDebugserverProcess (const char *hostname, 171 uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit 172 ProcessLaunchInfo &launch_info, 173 uint16_t &out_port); 174 175 void 176 DumpHistory(Stream &strm); 177 178 protected: 179 180 class History 181 { 182 public: 183 enum PacketType 184 { 185 ePacketTypeInvalid = 0, 186 ePacketTypeSend, 187 ePacketTypeRecv 188 }; 189 190 struct Entry 191 { EntryEntry192 Entry() : 193 packet(), 194 type (ePacketTypeInvalid), 195 bytes_transmitted (0), 196 packet_idx (0), 197 tid (LLDB_INVALID_THREAD_ID) 198 { 199 } 200 201 void ClearEntry202 Clear () 203 { 204 packet.clear(); 205 type = ePacketTypeInvalid; 206 bytes_transmitted = 0; 207 packet_idx = 0; 208 tid = LLDB_INVALID_THREAD_ID; 209 } 210 std::string packet; 211 PacketType type; 212 uint32_t bytes_transmitted; 213 uint32_t packet_idx; 214 lldb::tid_t tid; 215 }; 216 217 History (uint32_t size); 218 219 ~History (); 220 221 // For single char packets for ack, nack and /x03 222 void 223 AddPacket (char packet_char, 224 PacketType type, 225 uint32_t bytes_transmitted); 226 void 227 AddPacket (const std::string &src, 228 uint32_t src_len, 229 PacketType type, 230 uint32_t bytes_transmitted); 231 232 void 233 Dump (Stream &strm) const; 234 235 void 236 Dump (Log *log) const; 237 238 bool DidDumpToLog()239 DidDumpToLog () const 240 { 241 return m_dumped_to_log; 242 } 243 244 protected: 245 uint32_t GetFirstSavedPacketIndex()246 GetFirstSavedPacketIndex () const 247 { 248 if (m_total_packet_count < m_packets.size()) 249 return 0; 250 else 251 return m_curr_idx + 1; 252 } 253 254 uint32_t GetNumPacketsInHistory()255 GetNumPacketsInHistory () const 256 { 257 if (m_total_packet_count < m_packets.size()) 258 return m_total_packet_count; 259 else 260 return (uint32_t)m_packets.size(); 261 } 262 263 uint32_t GetNextIndex()264 GetNextIndex() 265 { 266 ++m_total_packet_count; 267 const uint32_t idx = m_curr_idx; 268 m_curr_idx = NormalizeIndex(idx + 1); 269 return idx; 270 } 271 272 uint32_t NormalizeIndex(uint32_t i)273 NormalizeIndex (uint32_t i) const 274 { 275 return i % m_packets.size(); 276 } 277 278 279 std::vector<Entry> m_packets; 280 uint32_t m_curr_idx; 281 uint32_t m_total_packet_count; 282 mutable bool m_dumped_to_log; 283 }; 284 285 PacketResult 286 SendPacket (const char *payload, 287 size_t payload_length); 288 289 PacketResult 290 SendPacketNoLock (const char *payload, 291 size_t payload_length); 292 293 PacketResult 294 ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout); 295 296 // Pop a packet from the queue in a thread safe manner 297 PacketResult 298 PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec); 299 300 PacketResult 301 WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response, 302 uint32_t timeout_usec, 303 bool sync_on_timeout); 304 305 bool 306 WaitForNotRunningPrivate (const TimeValue *timeout_ptr); 307 308 bool CompressionIsEnabled()309 CompressionIsEnabled () 310 { 311 return m_compression_type != CompressionType::None; 312 } 313 314 // If compression is enabled, decompress the packet in m_bytes and update 315 // m_bytes with the uncompressed version. 316 // Returns 'true' packet was decompressed and m_bytes is the now-decompressed text. 317 // Returns 'false' if unable to decompress or if the checksum was invalid. 318 // 319 // NB: Once the packet has been decompressed, checksum cannot be computed based 320 // on m_bytes. The checksum was for the compressed packet. 321 bool 322 DecompressPacket (); 323 324 //------------------------------------------------------------------ 325 // Classes that inherit from GDBRemoteCommunication can see and modify these 326 //------------------------------------------------------------------ 327 uint32_t m_packet_timeout; 328 uint32_t m_echo_number; 329 LazyBool m_supports_qEcho; 330 #ifdef ENABLE_MUTEX_ERROR_CHECKING 331 TrackingMutex m_sequence_mutex; 332 #else 333 Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time 334 #endif 335 Predicate<bool> m_public_is_running; 336 Predicate<bool> m_private_is_running; 337 History m_history; 338 bool m_send_acks; 339 bool m_is_platform; // Set to true if this class represents a platform, 340 // false if this class represents a debug session for 341 // a single process 342 343 CompressionType m_compression_type; 344 345 Error 346 StartListenThread (const char *hostname = "127.0.0.1", uint16_t port = 0); 347 348 bool 349 JoinListenThread (); 350 351 static lldb::thread_result_t 352 ListenThread (lldb::thread_arg_t arg); 353 354 // GDB-Remote read thread 355 // . this thread constantly tries to read from the communication 356 // class and stores all packets received in a queue. The usual 357 // threads read requests simply pop packets off the queue in the 358 // usual order. 359 // This setup allows us to intercept and handle async packets, such 360 // as the notify packet. 361 362 // This method is defined as part of communication.h 363 // when the read thread gets any bytes it will pass them on to this function 364 virtual void AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, lldb::ConnectionStatus status); 365 366 private: 367 368 std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue 369 lldb_private::Mutex m_packet_queue_mutex; // Mutex for accessing queue 370 Condition m_condition_queue_not_empty; // Condition variable to wait for packets 371 372 HostThread m_listen_thread; 373 std::string m_listen_url; 374 375 //------------------------------------------------------------------ 376 // For GDBRemoteCommunication only 377 //------------------------------------------------------------------ 378 DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication); 379 }; 380 381 } // namespace process_gdb_remote 382 } // namespace lldb_private 383 384 #endif // liblldb_GDBRemoteCommunication_h_ 385