Home | History | Annotate | Download | only in gdb-remote
      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 
     18 // Other libraries and framework includes
     19 // Project includes
     20 #include "lldb/lldb-public.h"
     21 #include "lldb/Core/Communication.h"
     22 #include "lldb/Core/Listener.h"
     23 #include "lldb/Host/Mutex.h"
     24 #include "lldb/Host/Predicate.h"
     25 #include "lldb/Host/TimeValue.h"
     26 
     27 #include "Utility/StringExtractorGDBRemote.h"
     28 
     29 class ProcessGDBRemote;
     30 
     31 class GDBRemoteCommunication : public lldb_private::Communication
     32 {
     33 public:
     34     enum
     35     {
     36         eBroadcastBitRunPacketSent = kLoUserBroadcastBit
     37     };
     38     //------------------------------------------------------------------
     39     // Constructors and Destructors
     40     //------------------------------------------------------------------
     41     GDBRemoteCommunication(const char *comm_name,
     42                            const char *listener_name,
     43                            bool is_platform);
     44 
     45     virtual
     46     ~GDBRemoteCommunication();
     47 
     48     char
     49     GetAck ();
     50 
     51     size_t
     52     SendAck ();
     53 
     54     size_t
     55     SendNack ();
     56 
     57     char
     58     CalculcateChecksum (const char *payload,
     59                         size_t payload_length);
     60 
     61     bool
     62     GetSequenceMutex (lldb_private::Mutex::Locker& locker, const char *failure_message = NULL);
     63 
     64     bool
     65     CheckForPacket (const uint8_t *src,
     66                     size_t src_len,
     67                     StringExtractorGDBRemote &packet);
     68     bool
     69     IsRunning() const
     70     {
     71         return m_public_is_running.GetValue();
     72     }
     73 
     74     bool
     75     GetSendAcks ()
     76     {
     77         return m_send_acks;
     78     }
     79 
     80     //------------------------------------------------------------------
     81     // Client and server must implement these pure virtual functions
     82     //------------------------------------------------------------------
     83     virtual bool
     84     GetThreadSuffixSupported () = 0;
     85 
     86     //------------------------------------------------------------------
     87     // Set the global packet timeout.
     88     //
     89     // For clients, this is the timeout that gets used when sending
     90     // packets and waiting for responses. For servers, this might not
     91     // get used, and if it doesn't this should be moved to the
     92     // GDBRemoteCommunicationClient.
     93     //------------------------------------------------------------------
     94     uint32_t
     95     SetPacketTimeout (uint32_t packet_timeout)
     96     {
     97         const uint32_t old_packet_timeout = m_packet_timeout;
     98         m_packet_timeout = packet_timeout;
     99         return old_packet_timeout;
    100     }
    101 
    102     uint32_t
    103     GetPacketTimeoutInMicroSeconds () const
    104     {
    105         return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
    106     }
    107     //------------------------------------------------------------------
    108     // Start a debugserver instance on the current host using the
    109     // supplied connection URL.
    110     //------------------------------------------------------------------
    111     lldb_private::Error
    112     StartDebugserverProcess (const char *connect_url,
    113                              const char *unix_socket_name,
    114                              lldb_private::ProcessLaunchInfo &launch_info);
    115 
    116     void
    117     DumpHistory(lldb_private::Stream &strm);
    118 
    119 protected:
    120 
    121     class History
    122     {
    123     public:
    124         enum PacketType
    125         {
    126             ePacketTypeInvalid = 0,
    127             ePacketTypeSend,
    128             ePacketTypeRecv
    129         };
    130 
    131         struct Entry
    132         {
    133             Entry() :
    134                 packet(),
    135                 type (ePacketTypeInvalid),
    136                 bytes_transmitted (0),
    137                 packet_idx (0),
    138                 tid (LLDB_INVALID_THREAD_ID)
    139             {
    140             }
    141 
    142             void
    143             Clear ()
    144             {
    145                 packet.clear();
    146                 type = ePacketTypeInvalid;
    147                 bytes_transmitted = 0;
    148                 packet_idx = 0;
    149                 tid = LLDB_INVALID_THREAD_ID;
    150             }
    151             std::string packet;
    152             PacketType type;
    153             uint32_t bytes_transmitted;
    154             uint32_t packet_idx;
    155             lldb::tid_t tid;
    156         };
    157 
    158         History (uint32_t size);
    159 
    160         ~History ();
    161 
    162         // For single char packets for ack, nack and /x03
    163         void
    164         AddPacket (char packet_char,
    165                    PacketType type,
    166                    uint32_t bytes_transmitted);
    167         void
    168         AddPacket (const std::string &src,
    169                    uint32_t src_len,
    170                    PacketType type,
    171                    uint32_t bytes_transmitted);
    172 
    173         void
    174         Dump (lldb_private::Stream &strm) const;
    175 
    176         void
    177         Dump (lldb_private::Log *log) const;
    178 
    179         bool
    180         DidDumpToLog () const
    181         {
    182             return m_dumped_to_log;
    183         }
    184 
    185 protected:
    186         uint32_t
    187         GetFirstSavedPacketIndex () const
    188         {
    189             if (m_total_packet_count < m_packets.size())
    190                 return 0;
    191             else
    192                 return m_curr_idx + 1;
    193         }
    194 
    195         uint32_t
    196         GetNumPacketsInHistory () const
    197         {
    198             if (m_total_packet_count < m_packets.size())
    199                 return m_total_packet_count;
    200             else
    201                 return (uint32_t)m_packets.size();
    202         }
    203 
    204         uint32_t
    205         GetNextIndex()
    206         {
    207             ++m_total_packet_count;
    208             const uint32_t idx = m_curr_idx;
    209             m_curr_idx = NormalizeIndex(idx + 1);
    210             return idx;
    211         }
    212 
    213         uint32_t
    214         NormalizeIndex (uint32_t i) const
    215         {
    216             return i % m_packets.size();
    217         }
    218 
    219 
    220         std::vector<Entry> m_packets;
    221         uint32_t m_curr_idx;
    222         uint32_t m_total_packet_count;
    223         mutable bool m_dumped_to_log;
    224     };
    225 
    226     size_t
    227     SendPacket (const char *payload,
    228                 size_t payload_length);
    229 
    230     size_t
    231     SendPacketNoLock (const char *payload,
    232                       size_t payload_length);
    233 
    234     size_t
    235     WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response,
    236                                                 uint32_t timeout_usec);
    237 
    238     bool
    239     WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
    240 
    241     //------------------------------------------------------------------
    242     // Classes that inherit from GDBRemoteCommunication can see and modify these
    243     //------------------------------------------------------------------
    244     uint32_t m_packet_timeout;
    245 #ifdef LLDB_CONFIGURATION_DEBUG
    246     lldb_private::TrackingMutex m_sequence_mutex;
    247 #else
    248     lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
    249 #endif
    250     lldb_private::Predicate<bool> m_public_is_running;
    251     lldb_private::Predicate<bool> m_private_is_running;
    252     History m_history;
    253     bool m_send_acks;
    254     bool m_is_platform; // Set to true if this class represents a platform,
    255                         // false if this class represents a debug session for
    256                         // a single process
    257 
    258 
    259 
    260 
    261 private:
    262     //------------------------------------------------------------------
    263     // For GDBRemoteCommunication only
    264     //------------------------------------------------------------------
    265     DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
    266 };
    267 
    268 #endif  // liblldb_GDBRemoteCommunication_h_
    269