forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			295 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			295 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- GDBRemoteCommunication.h --------------------------------*- C++ -*-===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#ifndef liblldb_GDBRemoteCommunication_h_
 | 
						|
#define liblldb_GDBRemoteCommunication_h_
 | 
						|
 | 
						|
// C Includes
 | 
						|
// C++ Includes
 | 
						|
#include <list>
 | 
						|
#include <string>
 | 
						|
 | 
						|
// Other libraries and framework includes
 | 
						|
// Project includes
 | 
						|
#include "lldb/lldb-public.h"
 | 
						|
#include "lldb/Core/Communication.h"
 | 
						|
#include "lldb/Core/Listener.h"
 | 
						|
#include "lldb/Host/Mutex.h"
 | 
						|
#include "lldb/Host/Predicate.h"
 | 
						|
#include "lldb/Host/TimeValue.h"
 | 
						|
 | 
						|
#include "Utility/StringExtractorGDBRemote.h"
 | 
						|
 | 
						|
class ProcessGDBRemote;
 | 
						|
 | 
						|
class GDBRemoteCommunication : public lldb_private::Communication
 | 
						|
{
 | 
						|
public:
 | 
						|
    enum
 | 
						|
    {
 | 
						|
        eBroadcastBitRunPacketSent = kLoUserBroadcastBit
 | 
						|
    };
 | 
						|
    
 | 
						|
    enum class PacketResult
 | 
						|
    {
 | 
						|
        Success = 0,        // Success
 | 
						|
        ErrorSendFailed,    // Error sending the packet
 | 
						|
        ErrorSendAck,       // Didn't get an ack back after sending a packet
 | 
						|
        ErrorReplyFailed,   // Error getting the reply
 | 
						|
        ErrorReplyTimeout,  // Timed out waiting for reply
 | 
						|
        ErrorReplyInvalid,  // Got a reply but it wasn't valid for the packet that was sent
 | 
						|
        ErrorReplyAck,      // Sending reply ack failed
 | 
						|
        ErrorDisconnected   // We were disconnected
 | 
						|
    };
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    // Constructors and Destructors
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    GDBRemoteCommunication(const char *comm_name, 
 | 
						|
                           const char *listener_name,
 | 
						|
                           bool is_platform);
 | 
						|
 | 
						|
    virtual
 | 
						|
    ~GDBRemoteCommunication();
 | 
						|
 | 
						|
    PacketResult
 | 
						|
    GetAck ();
 | 
						|
 | 
						|
    size_t
 | 
						|
    SendAck ();
 | 
						|
 | 
						|
    size_t
 | 
						|
    SendNack ();
 | 
						|
 | 
						|
    char
 | 
						|
    CalculcateChecksum (const char *payload,
 | 
						|
                        size_t payload_length);
 | 
						|
 | 
						|
    bool
 | 
						|
    GetSequenceMutex (lldb_private::Mutex::Locker& locker, const char *failure_message = NULL);
 | 
						|
 | 
						|
    bool
 | 
						|
    CheckForPacket (const uint8_t *src, 
 | 
						|
                    size_t src_len, 
 | 
						|
                    StringExtractorGDBRemote &packet);
 | 
						|
    bool
 | 
						|
    IsRunning() const
 | 
						|
    {
 | 
						|
        return m_public_is_running.GetValue();
 | 
						|
    }
 | 
						|
 | 
						|
    bool
 | 
						|
    GetSendAcks ()
 | 
						|
    {
 | 
						|
        return m_send_acks;
 | 
						|
    }
 | 
						|
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    // Client and server must implement these pure virtual functions
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    virtual bool
 | 
						|
    GetThreadSuffixSupported () = 0;
 | 
						|
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    // Set the global packet timeout.
 | 
						|
    //
 | 
						|
    // For clients, this is the timeout that gets used when sending
 | 
						|
    // packets and waiting for responses. For servers, this might not
 | 
						|
    // get used, and if it doesn't this should be moved to the
 | 
						|
    // GDBRemoteCommunicationClient.
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    uint32_t 
 | 
						|
    SetPacketTimeout (uint32_t packet_timeout)
 | 
						|
    {
 | 
						|
        const uint32_t old_packet_timeout = m_packet_timeout;
 | 
						|
        m_packet_timeout = packet_timeout;
 | 
						|
        return old_packet_timeout;
 | 
						|
    }
 | 
						|
 | 
						|
    uint32_t
 | 
						|
    GetPacketTimeoutInMicroSeconds () const
 | 
						|
    {
 | 
						|
        return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
 | 
						|
    }
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    // Start a debugserver instance on the current host using the
 | 
						|
    // supplied connection URL.
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    lldb_private::Error
 | 
						|
    StartDebugserverProcess (const char *hostname,
 | 
						|
                             uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
 | 
						|
                             lldb_private::ProcessLaunchInfo &launch_info,
 | 
						|
                             uint16_t &out_port);
 | 
						|
 | 
						|
    void
 | 
						|
    DumpHistory(lldb_private::Stream &strm);
 | 
						|
    
 | 
						|
protected:
 | 
						|
 | 
						|
    class History
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        enum PacketType
 | 
						|
        {
 | 
						|
            ePacketTypeInvalid = 0,
 | 
						|
            ePacketTypeSend,
 | 
						|
            ePacketTypeRecv
 | 
						|
        };
 | 
						|
 | 
						|
        struct Entry
 | 
						|
        {
 | 
						|
            Entry() :
 | 
						|
                packet(),
 | 
						|
                type (ePacketTypeInvalid),
 | 
						|
                bytes_transmitted (0),
 | 
						|
                packet_idx (0),
 | 
						|
                tid (LLDB_INVALID_THREAD_ID)
 | 
						|
            {
 | 
						|
            }
 | 
						|
            
 | 
						|
            void
 | 
						|
            Clear ()
 | 
						|
            {
 | 
						|
                packet.clear();
 | 
						|
                type = ePacketTypeInvalid;
 | 
						|
                bytes_transmitted = 0;
 | 
						|
                packet_idx = 0;
 | 
						|
                tid = LLDB_INVALID_THREAD_ID;
 | 
						|
            }
 | 
						|
            std::string packet;
 | 
						|
            PacketType type;
 | 
						|
            uint32_t bytes_transmitted;
 | 
						|
            uint32_t packet_idx;
 | 
						|
            lldb::tid_t tid;
 | 
						|
        };
 | 
						|
 | 
						|
        History (uint32_t size);
 | 
						|
        
 | 
						|
        ~History ();
 | 
						|
 | 
						|
        // For single char packets for ack, nack and /x03
 | 
						|
        void
 | 
						|
        AddPacket (char packet_char,
 | 
						|
                   PacketType type,
 | 
						|
                   uint32_t bytes_transmitted);
 | 
						|
        void
 | 
						|
        AddPacket (const std::string &src,
 | 
						|
                   uint32_t src_len,
 | 
						|
                   PacketType type,
 | 
						|
                   uint32_t bytes_transmitted);
 | 
						|
        
 | 
						|
        void
 | 
						|
        Dump (lldb_private::Stream &strm) const;
 | 
						|
 | 
						|
        void
 | 
						|
        Dump (lldb_private::Log *log) const;
 | 
						|
 | 
						|
        bool
 | 
						|
        DidDumpToLog () const
 | 
						|
        {
 | 
						|
            return m_dumped_to_log;
 | 
						|
        }
 | 
						|
    
 | 
						|
protected:
 | 
						|
        uint32_t
 | 
						|
        GetFirstSavedPacketIndex () const
 | 
						|
        {
 | 
						|
            if (m_total_packet_count < m_packets.size())
 | 
						|
                return 0;
 | 
						|
            else
 | 
						|
                return m_curr_idx + 1;
 | 
						|
        }
 | 
						|
 | 
						|
        uint32_t
 | 
						|
        GetNumPacketsInHistory () const
 | 
						|
        {
 | 
						|
            if (m_total_packet_count < m_packets.size())
 | 
						|
                return m_total_packet_count;
 | 
						|
            else
 | 
						|
                return (uint32_t)m_packets.size();
 | 
						|
        }
 | 
						|
 | 
						|
        uint32_t
 | 
						|
        GetNextIndex()
 | 
						|
        {
 | 
						|
            ++m_total_packet_count;
 | 
						|
            const uint32_t idx = m_curr_idx;
 | 
						|
            m_curr_idx = NormalizeIndex(idx + 1);
 | 
						|
            return idx;
 | 
						|
        }
 | 
						|
 | 
						|
        uint32_t
 | 
						|
        NormalizeIndex (uint32_t i) const
 | 
						|
        {
 | 
						|
            return i % m_packets.size();
 | 
						|
        }
 | 
						|
 | 
						|
        
 | 
						|
        std::vector<Entry> m_packets;
 | 
						|
        uint32_t m_curr_idx;
 | 
						|
        uint32_t m_total_packet_count;
 | 
						|
        mutable bool m_dumped_to_log;
 | 
						|
    };
 | 
						|
 | 
						|
    PacketResult
 | 
						|
    SendPacket (const char *payload,
 | 
						|
                size_t payload_length);
 | 
						|
 | 
						|
    PacketResult
 | 
						|
    SendPacketNoLock (const char *payload, 
 | 
						|
                      size_t payload_length);
 | 
						|
 | 
						|
    PacketResult
 | 
						|
    WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response, 
 | 
						|
                                                uint32_t timeout_usec);
 | 
						|
 | 
						|
    bool
 | 
						|
    WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
 | 
						|
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    // Classes that inherit from GDBRemoteCommunication can see and modify these
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    uint32_t m_packet_timeout;
 | 
						|
#ifdef ENABLE_MUTEX_ERROR_CHECKING
 | 
						|
    lldb_private::TrackingMutex m_sequence_mutex;
 | 
						|
#else
 | 
						|
    lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
 | 
						|
#endif
 | 
						|
    lldb_private::Predicate<bool> m_public_is_running;
 | 
						|
    lldb_private::Predicate<bool> m_private_is_running;
 | 
						|
    History m_history;
 | 
						|
    bool m_send_acks;
 | 
						|
    bool m_is_platform; // Set to true if this class represents a platform,
 | 
						|
                        // false if this class represents a debug session for
 | 
						|
                        // a single process
 | 
						|
    
 | 
						|
 | 
						|
    lldb_private::Error
 | 
						|
    StartListenThread (const char *hostname = "localhost",
 | 
						|
                       uint16_t port = 0);
 | 
						|
 | 
						|
    bool
 | 
						|
    JoinListenThread ();
 | 
						|
 | 
						|
    static lldb::thread_result_t
 | 
						|
    ListenThread (lldb::thread_arg_t arg);
 | 
						|
 | 
						|
private:
 | 
						|
    
 | 
						|
    lldb::thread_t m_listen_thread;
 | 
						|
    std::string m_listen_url;
 | 
						|
    
 | 
						|
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    // For GDBRemoteCommunication only
 | 
						|
    //------------------------------------------------------------------
 | 
						|
    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
 | 
						|
};
 | 
						|
 | 
						|
#endif  // liblldb_GDBRemoteCommunication_h_
 |