Added the ability to connect using "tcp://<host>:<port>" which is the

same as the old "connect://<host>:<port>". Also added the ability to
connect using "udp://<host>:<port>" which will open a connected 
datagram socket. I need to find a way to specify a non connected
datagram socket as well. 

We might need to start setting some settings in the URL itself, 
maybe something like:

udp://<host>:<port>?connected=yes
udp://<host>:<port>?connected=no

I am open to suggestions for URL settings.

Also did more work on the KDP darwin kernel plug-in.

 

llvm-svn: 135277
This commit is contained in:
Greg Clayton
2011-07-15 16:31:38 +00:00
parent e9d62935d3
commit 57508026c2
6 changed files with 278 additions and 262 deletions

View File

@@ -61,8 +61,11 @@ protected:
SocketListen (uint16_t listen_port_num, Error *error_ptr);
lldb::ConnectionStatus
SocketConnect (const char *host_and_port, Error *error_ptr);
ConnectTCP (const char *host_and_port, Error *error_ptr);
lldb::ConnectionStatus
ConnectUDP (const char *host_and_port, Error *error_ptr);
lldb::ConnectionStatus
NamedSocketAccept (const char *socket_name, Error *error_ptr);

View File

@@ -16,6 +16,12 @@
26368A3C126B697600E8659F /* darwin-debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26368A3B126B697600E8659F /* darwin-debug.cpp */; };
26368AF7126B960500E8659F /* darwin-debug in Resources */ = {isa = PBXBuildFile; fileRef = 26579F68126A25920007C5CB /* darwin-debug */; };
263E949F13661AEA00E7D1CE /* UnwindAssembly-x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263E949D13661AE400E7D1CE /* UnwindAssembly-x86.cpp */; };
2642FBAE13D003B400ED6808 /* CommunicationKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */; };
2642FBAF13D003B400ED6808 /* CommunicationKDP.h in Headers */ = {isa = PBXBuildFile; fileRef = 2642FBA913D003B400ED6808 /* CommunicationKDP.h */; };
2642FBB013D003B400ED6808 /* ProcessKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */; };
2642FBB113D003B400ED6808 /* ProcessKDP.h in Headers */ = {isa = PBXBuildFile; fileRef = 2642FBAB13D003B400ED6808 /* ProcessKDP.h */; };
2642FBB213D003B400ED6808 /* ProcessKDPLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBAC13D003B400ED6808 /* ProcessKDPLog.cpp */; };
2642FBB313D003B400ED6808 /* ProcessKDPLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 2642FBAD13D003B400ED6808 /* ProcessKDPLog.h */; };
264A97BF133918BC0017F0BE /* PlatformRemoteGDBServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264A97BD133918BC0017F0BE /* PlatformRemoteGDBServer.cpp */; };
264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D8D4F13661BD7003A368F /* UnwindAssembly.cpp */; };
265ABF6310F42EE900531910 /* DebugSymbols.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 265ABF6210F42EE900531910 /* DebugSymbols.framework */; };
@@ -640,6 +646,12 @@
263FEDA5112CC1DA00E4C208 /* ThreadSafeSTLMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSafeSTLMap.h; path = include/lldb/Core/ThreadSafeSTLMap.h; sourceTree = "<group>"; };
26424E3C125986CB0016D82C /* ValueObjectConstResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResult.cpp; path = source/Core/ValueObjectConstResult.cpp; sourceTree = "<group>"; };
26424E3E125986D30016D82C /* ValueObjectConstResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResult.h; path = include/lldb/Core/ValueObjectConstResult.h; sourceTree = "<group>"; };
2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommunicationKDP.cpp; sourceTree = "<group>"; };
2642FBA913D003B400ED6808 /* CommunicationKDP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommunicationKDP.h; sourceTree = "<group>"; };
2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessKDP.cpp; sourceTree = "<group>"; };
2642FBAB13D003B400ED6808 /* ProcessKDP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessKDP.h; sourceTree = "<group>"; };
2642FBAC13D003B400ED6808 /* ProcessKDPLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessKDPLog.cpp; sourceTree = "<group>"; };
2642FBAD13D003B400ED6808 /* ProcessKDPLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessKDPLog.h; sourceTree = "<group>"; };
264334381110F63100CDB6C6 /* ValueObjectRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectRegister.cpp; path = source/Core/ValueObjectRegister.cpp; sourceTree = "<group>"; };
2643343A1110F63C00CDB6C6 /* ValueObjectRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectRegister.h; path = include/lldb/Core/ValueObjectRegister.h; sourceTree = "<group>"; };
264723A511FA076E00DE380C /* CleanUp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CleanUp.h; path = include/lldb/Utility/CleanUp.h; sourceTree = "<group>"; };
@@ -1483,6 +1495,7 @@
isa = PBXGroup;
children = (
4CEE62F71145F1C70064CF93 /* GDB Remote */,
2642FBA713D003B400ED6808 /* MacOSX-Kernel */,
260C898B10F57C5600BB2B04 /* MacOSX-User */,
26B4666E11A2080F00CF6220 /* Utility */,
);
@@ -1723,6 +1736,19 @@
name = API;
sourceTree = "<group>";
};
2642FBA713D003B400ED6808 /* MacOSX-Kernel */ = {
isa = PBXGroup;
children = (
2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */,
2642FBA913D003B400ED6808 /* CommunicationKDP.h */,
2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */,
2642FBAB13D003B400ED6808 /* ProcessKDP.h */,
2642FBAC13D003B400ED6808 /* ProcessKDPLog.cpp */,
2642FBAD13D003B400ED6808 /* ProcessKDPLog.h */,
);
path = "MacOSX-Kernel";
sourceTree = "<group>";
};
264A97BC133918A30017F0BE /* GDB Server */ = {
isa = PBXGroup;
children = (
@@ -2686,6 +2712,9 @@
buildActionMask = 2147483647;
files = (
9A9E1F0113980943005AC039 /* InputReaderStack.h in Headers */,
2642FBAF13D003B400ED6808 /* CommunicationKDP.h in Headers */,
2642FBB113D003B400ED6808 /* ProcessKDP.h in Headers */,
2642FBB313D003B400ED6808 /* ProcessKDPLog.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3279,6 +3308,9 @@
26F4214413C6515B00E04E5E /* DynamicLoaderMacOSXKernel.cpp in Sources */,
94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */,
94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */,
2642FBAE13D003B400ED6808 /* CommunicationKDP.cpp in Sources */,
2642FBB013D003B400ED6808 /* ProcessKDP.cpp in Sources */,
2642FBB213D003B400ED6808 /* ProcessKDPLog.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -97,7 +97,15 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
}
else if (strstr(s, "connect://"))
{
return SocketConnect (s + strlen("connect://"), error_ptr);
return ConnectTCP (s + strlen("connect://"), error_ptr);
}
else if (strstr(s, "tcp://"))
{
return ConnectTCP (s + strlen("tcp://"), error_ptr);
}
else if (strstr(s, "udp://"))
{
return ConnectUDP (s + strlen("udp://"), error_ptr);
}
else if (strstr(s, "fd://"))
{
@@ -626,10 +634,10 @@ ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_p
}
ConnectionStatus
ConnectionFileDescriptor::SocketConnect (const char *host_and_port, Error *error_ptr)
ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr)
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
"%p ConnectionFileDescriptor::SocketConnect (host/port = %s)",
"%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)",
this, host_and_port);
Close (m_fd, NULL);
m_is_socket = true;
@@ -715,6 +723,96 @@ ConnectionFileDescriptor::SocketConnect (const char *host_and_port, Error *error
return eConnectionStatusSuccess;
}
ConnectionStatus
ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr)
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
"%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)",
this, host_and_port);
Close (m_fd, NULL);
m_is_socket = true;
RegularExpression regex ("([^:]+):([0-9]+)");
if (regex.Execute (host_and_port, 2) == false)
{
if (error_ptr)
error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
return eConnectionStatusError;
}
std::string host_str;
std::string port_str;
if (regex.GetMatchAtIndex (host_and_port, 1, host_str) == false ||
regex.GetMatchAtIndex (host_and_port, 2, port_str) == false)
{
if (error_ptr)
error_ptr->SetErrorStringWithFormat("invalid host:port specification '%s'", host_and_port);
return eConnectionStatusError;
}
int32_t port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
if (port == INT32_MIN)
{
if (error_ptr)
error_ptr->SetErrorStringWithFormat("invalid port '%s'", port_str.c_str());
return eConnectionStatusError;
}
// Create the socket
m_fd = ::socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (m_fd == -1)
{
if (error_ptr)
error_ptr->SetErrorToErrno();
return eConnectionStatusError;
}
m_should_close_fd = true;
// Enable local address reuse
SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
struct sockaddr_in sa;
::memset (&sa, 0, sizeof (sa));
sa.sin_family = AF_INET;
sa.sin_port = htons (port);
int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
if (inet_pton_result <= 0)
{
struct hostent *host_entry = gethostbyname (host_str.c_str());
if (host_entry)
host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
if (inet_pton_result <= 0)
{
if (error_ptr)
{
if (inet_pton_result == -1)
error_ptr->SetErrorToErrno();
else
error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
}
Close (m_fd, NULL);
return eConnectionStatusError;
}
}
if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
{
if (error_ptr)
error_ptr->SetErrorToErrno();
Close (m_fd, NULL);
return eConnectionStatusError;
}
// Keep our TCP packets coming without any delays.
SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
if (error_ptr)
error_ptr->Clear();
return eConnectionStatusSuccess;
}
#if defined(__MINGW32__) || defined(__MINGW64__)
typedef const char * set_socket_option_arg_type;
typedef char * get_socket_option_arg_type;

View File

@@ -16,6 +16,7 @@
// C++ Includes
// Other libraries and framework includes
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
@@ -41,7 +42,9 @@ CommunicationKDP::CommunicationKDP (const char *comm_name) :
m_sequence_mutex (Mutex::eMutexTypeRecursive),
m_public_is_running (false),
m_private_is_running (false),
m_send_acks (true)
m_session_key (0),
m_request_sequence_id (0),
m_exception_sequence_id (0)
{
}
@@ -56,110 +59,68 @@ CommunicationKDP::~CommunicationKDP()
}
}
char
CommunicationKDP::CalculcateChecksum (const char *payload, size_t payload_length)
{
int checksum = 0;
// We only need to compute the checksum if we are sending acks
if (GetSendAcks ())
{
for (size_t i = 0; i < payload_length; ++i)
checksum += payload[i];
}
return checksum & 255;
}
size_t
CommunicationKDP::SendAck ()
{
LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (log)
log->Printf ("send packet: +");
ConnectionStatus status = eConnectionStatusSuccess;
char ack_char = '+';
return Write (&ack_char, 1, status, NULL);
}
size_t
CommunicationKDP::SendNack ()
{
LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (log)
log->Printf ("send packet: -");
ConnectionStatus status = eConnectionStatusSuccess;
char nack_char = '-';
return Write (&nack_char, 1, status, NULL);
}
size_t
CommunicationKDP::SendPacket (lldb_private::StreamString &payload)
bool
CommunicationKDP::SendRequestPacket (const StreamString &request_packet)
{
Mutex::Locker locker(m_sequence_mutex);
const std::string &p (payload.GetString());
return SendPacketNoLock (p.c_str(), p.size());
return SendRequestPacketNoLock (request_packet);
}
size_t
CommunicationKDP::SendPacket (const char *payload)
void
CommunicationKDP::MakeRequestPacketHeader (RequestType request_type,
StreamString &request_packet)
{
Mutex::Locker locker(m_sequence_mutex);
return SendPacketNoLock (payload, ::strlen (payload));
request_packet.Clear();
request_packet.PutHex32 (request_type); // Set the request type
request_packet.PutHex8 (ePacketTypeRequest); // Set the packet type
request_packet.PutHex8 (++m_request_sequence_id); // Sequence number
request_packet.PutHex16 (0); // Pad1 and Pad2 bytes
request_packet.PutHex32 (m_session_key); // Session key
}
size_t
CommunicationKDP::SendPacket (const char *payload, size_t payload_length)
{
Mutex::Locker locker(m_sequence_mutex);
return SendPacketNoLock (payload, payload_length);
}
size_t
CommunicationKDP::SendPacketNoLock (const char *payload, size_t payload_length)
bool
CommunicationKDP::SendRequestPacketNoLock (const StreamString &request_packet)
{
if (IsConnected())
{
StreamString packet(0, 4, eByteOrderBig);
packet.PutChar('$');
packet.Write (payload, payload_length);
packet.PutChar('#');
packet.PutHex8(CalculcateChecksum (payload, payload_length));
const char *packet_data = request_packet.GetData();
const size_t packet_size = request_packet.GetSize();
LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (log)
log->Printf ("send packet: %.*s", (int)packet.GetSize(), packet.GetData());
{
StreamString log_strm;
DataExtractor data (packet_data,
packet_size,
request_packet.GetByteOrder(),
request_packet.GetAddressByteSize());
data.Dump (&log_strm,
0,
eFormatBytes,
1,
packet_size,
32, // Num bytes per line
0, // Base address
0,
0);
log->Printf("request packet: <%u>\n%s", packet_size, log_strm.GetString().c_str());
}
ConnectionStatus status = eConnectionStatusSuccess;
size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
if (bytes_written == packet.GetSize())
{
if (GetSendAcks ())
{
if (GetAck () != '+')
{
printf("get ack failed...");
return 0;
}
}
}
else
{
LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (log)
log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData());
}
return bytes_written;
}
return 0;
}
char
CommunicationKDP::GetAck ()
{
StringExtractor packet;
if (WaitForPacketWithTimeoutMicroSeconds (packet, GetPacketTimeoutInMicroSeconds ()) == 1)
return packet.GetChar();
return 0;
size_t bytes_written = Write (packet_data,
packet_size,
status,
NULL);
if (bytes_written == packet_size)
return true;
if (log)
log->Printf ("error: failed to send packet entire packet %zu of %zu bytes sent", bytes_written, packet_size);
}
return false;
}
bool
@@ -262,142 +223,30 @@ CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, StringExtr
// Parse up the packets into gdb remote packets
if (!m_bytes.empty())
{
// end_idx must be one past the last valid packet byte. Start
// it off with an invalid value that is the same as the current
// index.
size_t content_start = 0;
size_t content_length = 0;
size_t total_length = 0;
size_t checksum_idx = std::string::npos;
switch (m_bytes[0])
{
case '+': // Look for ack
case '-': // Look for cancel
case '\x03': // ^C to halt target
content_length = total_length = 1; // The command is one byte long...
break;
case '$':
// Look for a standard gdb packet?
{
size_t hash_pos = m_bytes.find('#');
if (hash_pos != std::string::npos)
{
if (hash_pos + 2 < m_bytes.size())
{
checksum_idx = hash_pos + 1;
// Skip the dollar sign
content_start = 1;
// Don't include the # in the content or the $ in the content length
content_length = hash_pos - 1;
total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
}
else
{
// Checksum bytes aren't all here yet
content_length = std::string::npos;
}
}
}
break;
default:
{
// We have an unexpected byte and we need to flush all bad
// data that is in m_bytes, so we need to find the first
// byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
// or '$' character (start of packet header) or of course,
// the end of the data in m_bytes...
const size_t bytes_len = m_bytes.size();
bool done = false;
uint32_t idx;
for (idx = 1; !done && idx < bytes_len; ++idx)
{
switch (m_bytes[idx])
{
case '+':
case '-':
case '\x03':
case '$':
done = true;
break;
default:
break;
}
}
if (log)
log->Printf ("CommunicationKDP::%s tossing %u junk bytes: '%.*s'",
__FUNCTION__, idx, idx, m_bytes.c_str());
m_bytes.erase(0, idx);
}
break;
}
if (content_length == std::string::npos)
{
packet.Clear();
return false;
}
else if (total_length > 0)
{
// We have a valid packet...
assert (content_length <= m_bytes.size());
assert (total_length <= m_bytes.size());
assert (content_length <= total_length);
bool success = true;
std::string &packet_str = packet.GetStringRef();
packet_str.assign (m_bytes, content_start, content_length);
if (m_bytes[0] == '$')
{
assert (checksum_idx < m_bytes.size());
if (::isxdigit (m_bytes[checksum_idx+0]) ||
::isxdigit (m_bytes[checksum_idx+1]))
{
if (GetSendAcks ())
{
const char *packet_checksum_cstr = &m_bytes[checksum_idx];
char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
success = packet_checksum == actual_checksum;
if (!success)
{
if (log)
log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
(int)(total_length),
m_bytes.c_str(),
(uint8_t)packet_checksum,
(uint8_t)actual_checksum);
}
// Send the ack or nack if needed
if (!success)
SendNack();
else
SendAck();
}
if (success)
{
if (log)
log->Printf ("read packet: %.*s", (int)(total_length), m_bytes.c_str());
}
}
else
{
success = false;
if (log)
log->Printf ("error: invalid checksum in packet: '%s'\n", (int)(total_length), m_bytes.c_str());
}
}
m_bytes.erase(0, total_length);
packet.SetFilePos(0);
return success;
}
// TODO: Figure out if we have a full packet reply
}
packet.Clear();
return false;
}
CommunicationKDP::ErrorType
CommunicationKDP::Connect (uint16_t reply_port,
uint16_t exc_port,
const char *greeting)
{
StreamString request_packet (Stream::eBinary, 4, eByteOrderLittle);
MakeRequestPacketHeader (eRequestTypeConnect, request_packet);
request_packet.PutHex16(reply_port);
request_packet.PutHex16(exc_port);
request_packet.PutCString(greeting);
return eErrorUnimplemented;
}
CommunicationKDP::ErrorType
CommunicationKDP::Disconnect ()
{
return eErrorUnimplemented;
}

View File

@@ -33,6 +33,53 @@ public:
{
eBroadcastBitRunPacketSent = kLoUserBroadcastBit
};
const static uint32_t kMaxPacketSize = 1200;
const static uint32_t kMaxDataSize = 1024;
typedef enum
{
eRequestTypeConnect = 0u,
eRequestTypeDisconnect,
eRequestTypeHostInfo,
eRequestTypeVersion,
eRequestTypeMaxBytes,
eRequestTypeReadMemory,
eRequestTypeWriteMemory,
eRequestTypeReadRegisters,
eRequestTypeWriteRegisters,
eRequestTypeLoad,
eRequestTypeImagePath,
eRequestTypeSuspend,
eRequestTypeResume,
eRequestTypeException,
eRequestTypeTermination,
eRequestTypeBreakpointSet,
eRequestTypeBreakpointRemove,
eRequestTypeRegions,
eRequestTypeReattach,
eRequestTypeHostReboot,
eRequestTypeReadMemory64,
eRequestTypeWriteMemory64,
eRequestTypeBreakpointSet64,
eRequestTypeBreakpointRemove64,
eRequestTypeKernelVersion
} RequestType;
typedef enum
{
eErrorSuccess = 0,
eErrorAlreadyConnected,
eErrorPacketToBig,
eErrorInvalidRegisterFlavor,
eErrorUnimplemented
} ErrorType;
typedef enum
{
ePacketTypeRequest = 0u,
ePacketTypeReply = 1u
} PacketType;
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
@@ -41,34 +88,14 @@ public:
virtual
~CommunicationKDP();
size_t
SendPacket (const char *payload);
size_t
SendPacket (const char *payload,
size_t payload_length);
size_t
SendPacket (lldb_private::StreamString &response);
bool
SendRequestPacket (const lldb_private::StreamString &request_packet);
// Wait for a packet within 'nsec' seconds
size_t
WaitForPacketWithTimeoutMicroSeconds (StringExtractor &response,
uint32_t usec);
char
GetAck ();
size_t
SendAck ();
size_t
SendNack ();
char
CalculcateChecksum (const char *payload,
size_t payload_length);
bool
GetSequenceMutex(lldb_private::Mutex::Locker& locker);
@@ -82,12 +109,6 @@ public:
return m_public_is_running.GetValue();
}
bool
GetSendAcks ()
{
return m_send_acks;
}
//------------------------------------------------------------------
// Set the global packet timeout.
//
@@ -119,12 +140,19 @@ public:
lldb_private::ProcessLaunchInfo &launch_info);
ErrorType
Connect (uint16_t reply_port,
uint16_t exc_port,
const char *greeting);
ErrorType
Disconnect ();
protected:
typedef std::list<std::string> packet_collection;
size_t
SendPacketNoLock (const char *payload,
size_t payload_length);
bool
SendRequestPacketNoLock (const lldb_private::StreamString &request_packet);
size_t
WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractor &response,
@@ -133,6 +161,10 @@ protected:
bool
WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
void
MakeRequestPacketHeader (RequestType request_type,
lldb_private::StreamString &request_packet);
//------------------------------------------------------------------
// Classes that inherit from CommunicationKDP can see and modify these
//------------------------------------------------------------------
@@ -140,8 +172,9 @@ protected:
lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
lldb_private::Predicate<bool> m_public_is_running;
lldb_private::Predicate<bool> m_private_is_running;
bool m_send_acks;
uint32_t m_session_key;
uint8_t m_request_sequence_id;
uint8_t m_exception_sequence_id;
private:
//------------------------------------------------------------------
// For CommunicationKDP only

View File

@@ -16,6 +16,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/Target.h"
// Project includes
#include "ProcessKDP.h"
@@ -414,7 +415,7 @@ ProcessKDP::DoDetach()
m_thread_list.DiscardThreadPlans();
size_t response_size = m_comm.SendPacket ("D", 1);
size_t response_size = m_comm.Disconnect ();
if (log)
{
if (response_size)