Finally tracked down the racy condition that would hose up our debug

sessions: When continue packet has been sent and an interrupt packet was
quickly sent, it would get read at the same time:

$c#00\x03

There was an error where the packet end index was always being computed 
incorrectly by debugserver, but it wouldn't matter if there weren't extra
bytes on the end (the hex \x03 interrupt byte in this case). The first
'$' last 3 bytes of the data in the packet buffer were being trimmed
(trying to trim the '#' + checksum (#XX)) which made:

c#

And this would then be passed to the handle routine for the 'c' packet which
would see an extra character at the end and assume it was going to be in the
form c[addr] where "[addr]" was a hex address to resume at and this would
result in a malformed packet response. This is now fixed and everything works
great.

Another issue was issuing async packets correctly by doing correct handshakes
between the thread that wants to send the async packet, and the thread that
is tracking the current run.

Added a write lock to the communication class as well to make sure you never
get two threads trying to write data at the same time. This wasn't happening,
but it is a good idea to make sure it doesn't.

llvm-svn: 124369
This commit is contained in:
Greg Clayton 2011-01-27 09:02:32 +00:00
parent 13e04aef2a
commit 7ec3d40ec0
5 changed files with 158 additions and 112 deletions

View File

@ -358,7 +358,8 @@ protected:
lldb::thread_t m_read_thread; ///< The read thread handle in case we need to cancel the thread.
bool m_read_thread_enabled;
std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function.
Mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes.
Mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes.
Mutex m_write_mutex; ///< Don't let multiple threads write at the same time...
ReadThreadBytesReceived m_callback;
void *m_callback_baton;
bool m_close_on_eof;

View File

@ -32,6 +32,7 @@ Communication::Communication(const char *name) :
m_read_thread_enabled (false),
m_bytes(),
m_bytes_mutex (Mutex::eMutexTypeRecursive),
m_write_mutex (Mutex::eMutexTypeNormal),
m_callback (NULL),
m_callback_baton (NULL),
m_close_on_eof (true)
@ -205,6 +206,7 @@ Communication::Write (const void *src, size_t src_len, ConnectionStatus &status,
{
lldb::ConnectionSP connection_sp (m_connection_sp);
Mutex::Locker (m_write_mutex);
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
"%p Communication::Write (src = %p, src_len = %zu) connection = %p",
this,

View File

@ -134,6 +134,7 @@ GDBRemoteCommunication::SendPacketAndWaitForResponse
TimeValue timeout_time;
timeout_time = TimeValue::Now();
timeout_time.OffsetWithSeconds (timeout_seconds);
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (GetSequenceMutex (locker))
{
@ -149,24 +150,53 @@ GDBRemoteCommunication::SendPacketAndWaitForResponse
m_async_timeout = timeout_seconds;
m_async_packet_predicate.SetValue (true, eBroadcastNever);
if (log)
log->Printf ("async: async packet = %s", m_async_packet.c_str());
bool timed_out = false;
bool sent_interrupt = false;
if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
{
if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
if (sent_interrupt)
{
response = m_async_response;
return response.GetStringRef().size();
if (log)
log->Printf ("async: sent interrupt");
if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
{
if (log)
log->Printf ("async: got response");
response = m_async_response;
return response.GetStringRef().size();
}
else
{
if (log)
log->Printf ("async: timed out waiting for response");
}
// Make sure we wait until the continue packet has been sent again...
if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
{
if (log)
log->Printf ("async: timed out waiting for process to resume");
}
}
else
{
// We had a racy condition where we went to send the interrupt
// yet we were able to get the loc
}
}
// if (timed_out)
// m_error.SetErrorString("Timeout.");
// else
// m_error.SetErrorString("Unknown error.");
else
{
if (log)
log->Printf ("async: failed to interrupt");
}
}
else
{
// m_error.SetErrorString("Sequence mutex is locked.");
if (log)
log->Printf ("mutex taken and send_async == false, aborting packet");
}
}
return 0;
@ -212,17 +242,23 @@ GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
Mutex::Locker locker(m_sequence_mutex);
StateType state = eStateRunning;
if (SendPacket(payload, packet_length) == 0)
state = eStateInvalid;
BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
m_public_is_running.SetValue (true, eBroadcastNever);
m_private_is_running.SetValue (true, eBroadcastNever);
// Set the starting continue packet into "continue_packet". This packet
// make change if we are interrupted and we continue after an async packet...
std::string continue_packet(payload, packet_length);
while (state == eStateRunning)
{
if (log)
log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...)", __FUNCTION__);
log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
state = eStateInvalid;
m_private_is_running.SetValue (true, eBroadcastNever);
if (log)
log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
if (WaitForPacket (response, (TimeValue*)NULL))
{
@ -280,32 +316,28 @@ GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
Host::GetSignalAsCString (signo),
Host::GetSignalAsCString (async_signal));
if (SendPacket(signal_packet, signal_packet_len) == 0)
{
if (log)
log->Printf ("async: error: failed to resume with %s",
Host::GetSignalAsCString (async_signal));
state = eStateExited;
break;
}
else
{
m_private_is_running.SetValue (true, eBroadcastNever);
continue;
}
// Set the continue packet to resume...
continue_packet.assign(signal_packet, signal_packet_len);
continue;
}
}
else if (m_async_packet_predicate.GetValue())
{
if (log)
log->Printf ("async: send async packet: %s",
m_async_packet.c_str());
// We are supposed to send an asynchronous packet while
// we are running.
m_async_response.Clear();
if (!m_async_packet.empty())
if (m_async_packet.empty())
{
if (log)
log->Printf ("async: error: empty async packet");
}
else
{
if (log)
log->Printf ("async: sending packet: %s",
m_async_packet.c_str());
SendPacketAndWaitForResponse (&m_async_packet[0],
m_async_packet.size(),
m_async_response,
@ -313,25 +345,13 @@ GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
false);
}
// Let the other thread that was trying to send the async
// packet know that the packet has been sent.
// packet know that the packet has been sent and response is
// ready...
m_async_packet_predicate.SetValue(false, eBroadcastAlways);
if (log)
log->Printf ("async: resume after async response received: %s",
m_async_response.GetStringRef().c_str());
// Continue again
if (SendPacket("c", 1) == 0)
{
// Failed to send the continue packet
state = eStateExited;
break;
}
else
{
m_private_is_running.SetValue (true, eBroadcastNever);
continue;
}
// Set the continue packet to resume...
continue_packet.assign (1, 'c');
continue;
}
// Stop with signal and thread info
state = eStateStopped;
@ -477,8 +497,9 @@ GDBRemoteCommunication::SendInterrupt
{
sent_interrupt = false;
timed_out = false;
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (IsConnected() && IsRunning())
if (IsRunning())
{
// Only send an interrupt if our debugserver is running...
if (GetSequenceMutex (locker) == false)
@ -493,14 +514,35 @@ GDBRemoteCommunication::SendInterrupt
timeout = TimeValue::Now();
timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
}
size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
if (Write (&ctrl_c, 1, status, NULL) > 0)
if (bytes_written > 0)
{
sent_interrupt = true;
if (seconds_to_wait_for_stop)
{
m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out);
if (log)
log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
}
else
{
if (log)
log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
}
return true;
}
else
{
if (log)
log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
}
}
else
{
if (log)
log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
}
}
return false;

View File

@ -383,7 +383,7 @@ RNBRemote::GetPacketPayload (std::string &return_packet)
}
}
}
break;
break;
default:
DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s tossing unexpected packet???? %s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
@ -403,9 +403,9 @@ RNBRemote::HandlePacket_UNIMPLEMENTED (const char* p)
}
rnb_err_t
RNBRemote::HandlePacket_ILLFORMED (const char *description)
RNBRemote::HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description)
{
DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s sending ILLFORMED", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
DNBLogThreadedIf (LOG_RNB_PACKETS, "%8u %s:%i ILLFORMED: '%s' (%s)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), file, line, __FUNCTION__, p);
return SendPacket ("E03");
}
@ -583,8 +583,9 @@ RNBRemote::CommDataReceived(const std::string& new_data)
}
else
{
// Add two for the checksum bytes
end_idx += 4;
// Add two for the checksum bytes and 1 to point to the
// byte just past the end of this packet
end_idx += 2 + 1;
}
break;
@ -1125,12 +1126,12 @@ RNBRemote::HandlePacket_A (const char *p)
{
if (p == NULL || *p == '\0')
{
return HandlePacket_ILLFORMED ("Null packet for 'A' pkt");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Null packet for 'A' pkt");
}
p++;
if (p == '\0' || !isdigit (*p))
{
return HandlePacket_ILLFORMED ("arglen not specified on 'A' pkt");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not specified on 'A' pkt");
}
/* I promise I don't modify it anywhere in this function. strtoul()'s
@ -1150,11 +1151,11 @@ RNBRemote::HandlePacket_A (const char *p)
arglen = strtoul (buf, &c, 10);
if (errno != 0 && arglen == 0)
{
return HandlePacket_ILLFORMED ("arglen not a number on 'A' pkt");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not a number on 'A' pkt");
}
if (*c != ',')
{
return HandlePacket_ILLFORMED ("arglen not followed by comma on 'A' pkt");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt");
}
buf = c + 1;
@ -1162,11 +1163,11 @@ RNBRemote::HandlePacket_A (const char *p)
argnum = strtoul (buf, &c, 10);
if (errno != 0 && argnum == 0)
{
return HandlePacket_ILLFORMED ("argnum not a number on 'A' pkt");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "argnum not a number on 'A' pkt");
}
if (*c != ',')
{
return HandlePacket_ILLFORMED ("arglen not followed by comma on 'A' pkt");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt");
}
buf = c + 1;
@ -1183,7 +1184,7 @@ RNBRemote::HandlePacket_A (const char *p)
int ch = strtoul (smallbuf, NULL, 16);
if (errno != 0 && ch == 0)
{
return HandlePacket_ILLFORMED ("non-hex char in arg on 'A' pkt");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'A' pkt");
}
arg.push_back(ch);
@ -1209,7 +1210,7 @@ RNBRemote::HandlePacket_H (const char *p)
p++; // skip 'H'
if (*p != 'c' && *p != 'g')
{
return HandlePacket_ILLFORMED ("Missing 'c' or 'g' type in H packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing 'c' or 'g' type in H packet");
}
if (!m_ctx.HasValidProcessID())
@ -1223,7 +1224,7 @@ RNBRemote::HandlePacket_H (const char *p)
nub_thread_t tid = strtoul (p + 1, NULL, 16);
if (errno != 0 && tid == 0)
{
return HandlePacket_ILLFORMED ("Invalid thread number in H packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in H packet");
}
if (*p == 'c')
SetContinueThread (tid);
@ -1333,12 +1334,12 @@ RNBRemote::HandlePacket_qThreadExtraInfo (const char *p)
sequence of letters encoded in as 2-hex-chars-per-letter. */
p += strlen ("qThreadExtraInfo");
if (*p++ != ',')
return HandlePacket_ILLFORMED ("Ill formed qThreadExtraInfo packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Illformed qThreadExtraInfo packet");
errno = 0;
nub_thread_t tid = strtoul (p, NULL, 16);
if (errno != 0 && tid == 0)
{
return HandlePacket_ILLFORMED ("Invalid thread number in qThreadExtraInfo packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in qThreadExtraInfo packet");
}
const char * threadInfo = DNBThreadGetInfo(pid, tid);
@ -1760,7 +1761,7 @@ RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
uint32_t size = strtoul (p, NULL, 16);
if (errno != 0 && size == 0)
{
return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPayloadSize packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet");
}
m_max_payload_size = size;
return SendPacket ("OK");
@ -1777,7 +1778,7 @@ RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
uint32_t size = strtoul (p, NULL, 16);
if (errno != 0 && size == 0)
{
return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPacketSize packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet");
}
m_max_payload_size = size - 5;
return SendPacket ("OK");
@ -2050,7 +2051,7 @@ RNBRemote::HandlePacket_M (const char *p)
{
if (p == NULL || p[0] == '\0' || strlen (p) < 3)
{
return HandlePacket_ILLFORMED ("Too short M packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet");
}
char *c;
@ -2059,11 +2060,11 @@ RNBRemote::HandlePacket_M (const char *p)
nub_addr_t addr = strtoull (p, &c, 16);
if (errno != 0 && addr == 0)
{
return HandlePacket_ILLFORMED ("Invalid address in M packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet");
}
if (*c != ',')
{
return HandlePacket_ILLFORMED ("Comma sep missing in M packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet");
}
/* Advance 'p' to the length part of the packet. */
@ -2073,7 +2074,7 @@ RNBRemote::HandlePacket_M (const char *p)
uint32_t length = strtoul (p, &c, 16);
if (errno != 0 && length == 0)
{
return HandlePacket_ILLFORMED ("Invalid length in M packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet");
}
if (length == 0)
{
@ -2082,7 +2083,7 @@ RNBRemote::HandlePacket_M (const char *p)
if (*c != ':')
{
return HandlePacket_ILLFORMED ("Missing colon in M packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet");
}
/* Advance 'p' to the data part of the packet. */
p += (c - p) + 1;
@ -2090,7 +2091,7 @@ RNBRemote::HandlePacket_M (const char *p)
int datalen = strlen (p);
if (datalen & 0x1)
{
return HandlePacket_ILLFORMED ("Uneven # of hex chars for data in M packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet");
}
if (datalen == 0)
{
@ -2110,7 +2111,7 @@ RNBRemote::HandlePacket_M (const char *p)
uint8_t byte = strtoul (hexbuf, NULL, 16);
if (errno != 0 && byte == 0)
{
return HandlePacket_ILLFORMED ("Invalid hex byte in M packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet");
}
*i++ = byte;
p += 2;
@ -2129,7 +2130,7 @@ RNBRemote::HandlePacket_m (const char *p)
{
if (p == NULL || p[0] == '\0' || strlen (p) < 3)
{
return HandlePacket_ILLFORMED ("Too short m packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet");
}
char *c;
@ -2138,11 +2139,11 @@ RNBRemote::HandlePacket_m (const char *p)
nub_addr_t addr = strtoull (p, &c, 16);
if (errno != 0 && addr == 0)
{
return HandlePacket_ILLFORMED ("Invalid address in m packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet");
}
if (*c != ',')
{
return HandlePacket_ILLFORMED ("Comma sep missing in m packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet");
}
/* Advance 'p' to the length part of the packet. */
@ -2152,7 +2153,7 @@ RNBRemote::HandlePacket_m (const char *p)
uint32_t length = strtoul (p, NULL, 16);
if (errno != 0 && length == 0)
{
return HandlePacket_ILLFORMED ("Invalid length in m packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
}
if (length == 0)
{
@ -2181,7 +2182,7 @@ RNBRemote::HandlePacket_X (const char *p)
{
if (p == NULL || p[0] == '\0' || strlen (p) < 3)
{
return HandlePacket_ILLFORMED ("Too short X packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
}
char *c;
@ -2190,11 +2191,11 @@ RNBRemote::HandlePacket_X (const char *p)
nub_addr_t addr = strtoull (p, &c, 16);
if (errno != 0 && addr == 0)
{
return HandlePacket_ILLFORMED ("Invalid address in X packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
}
if (*c != ',')
{
return HandlePacket_ILLFORMED ("Comma sep missing in X packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
}
/* Advance 'p' to the length part of the packet. */
@ -2204,7 +2205,7 @@ RNBRemote::HandlePacket_X (const char *p)
int length = strtoul (p, NULL, 16);
if (errno != 0 && length == 0)
{
return HandlePacket_ILLFORMED ("Invalid length in m packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
}
// I think gdb sends a zero length write request to test whether this
@ -2250,7 +2251,7 @@ RNBRemote::HandlePacket_g (const char *p)
nub_process_t pid = m_ctx.ProcessID ();
nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
if (tid == INVALID_NUB_THREAD)
return HandlePacket_ILLFORMED ("No thread specified in p packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
if (m_use_native_regs)
{
@ -2298,7 +2299,7 @@ RNBRemote::HandlePacket_G (const char *p)
nub_process_t pid = m_ctx.ProcessID();
nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
if (tid == INVALID_NUB_THREAD)
return HandlePacket_ILLFORMED ("No thread specified in p packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
if (m_use_native_regs)
{
@ -2491,7 +2492,7 @@ RNBRemote::HandlePacket_v (const char *p)
errno = 0;
thread_action.signal = strtoul (c, &c, 16);
if (errno != 0)
return HandlePacket_ILLFORMED ("Could not parse signal in vCont packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
// Fall through to next case...
case 'c':
@ -2503,7 +2504,7 @@ RNBRemote::HandlePacket_v (const char *p)
errno = 0;
thread_action.signal = strtoul (c, &c, 16);
if (errno != 0)
return HandlePacket_ILLFORMED ("Could not parse signal in vCont packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
// Fall through to next case...
case 's':
@ -2514,7 +2515,7 @@ RNBRemote::HandlePacket_v (const char *p)
break;
default:
rnb_err = HandlePacket_ILLFORMED ("Unsupported action in vCont packet");
rnb_err = HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet");
break;
}
if (*c == ':')
@ -2522,7 +2523,7 @@ RNBRemote::HandlePacket_v (const char *p)
errno = 0;
thread_action.tid = strtoul (++c, &c, 16);
if (errno != 0)
return HandlePacket_ILLFORMED ("Could not parse thread number in vCont packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet");
}
thread_actions.Append (thread_action);
@ -2553,7 +2554,7 @@ RNBRemote::HandlePacket_v (const char *p)
int ch = strtoul (smallbuf, NULL, 16);
if (errno != 0 && ch == 0)
{
return HandlePacket_ILLFORMED ("non-hex char in arg on 'vAttachWait' pkt");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
}
attach_name.push_back(ch);
@ -2578,7 +2579,7 @@ RNBRemote::HandlePacket_v (const char *p)
int ch = strtoul (smallbuf, NULL, 16);
if (errno != 0 && ch == 0)
{
return HandlePacket_ILLFORMED ("non-hex char in arg on 'vAttachWait' pkt");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
}
attach_name.push_back(ch);
@ -2638,7 +2639,7 @@ RNBRemote::HandlePacket_T (const char *p)
p++;
if (p == NULL || *p == '\0')
{
return HandlePacket_ILLFORMED ("No thread specified in T packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet");
}
if (!m_ctx.HasValidProcessID())
{
@ -2648,7 +2649,7 @@ RNBRemote::HandlePacket_T (const char *p)
nub_thread_t tid = strtoul (p, NULL, 16);
if (errno != 0 && tid == 0)
{
return HandlePacket_ILLFORMED ("Could not parse thread number in T packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet");
}
nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid);
@ -2665,7 +2666,7 @@ rnb_err_t
RNBRemote::HandlePacket_z (const char *p)
{
if (p == NULL || *p == '\0')
return HandlePacket_ILLFORMED ("No thread specified in z packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet");
if (!m_ctx.HasValidProcessID())
return SendPacket ("E15");
@ -2674,22 +2675,22 @@ RNBRemote::HandlePacket_z (const char *p)
char break_type = *p++;
if (*p++ != ',')
return HandlePacket_ILLFORMED ("Comma separator missing in z packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
char *c = NULL;
nub_process_t pid = m_ctx.ProcessID();
errno = 0;
nub_addr_t addr = strtoull (p, &c, 16);
if (errno != 0 && addr == 0)
return HandlePacket_ILLFORMED ("Invalid address in z packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet");
p = c;
if (*p++ != ',')
return HandlePacket_ILLFORMED ("Comma separator missing in z packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
errno = 0;
uint32_t byte_size = strtoul (p, &c, 16);
if (errno != 0 && byte_size == 0)
return HandlePacket_ILLFORMED ("Invalid length in z packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet");
if (packet_cmd == 'Z')
{
@ -2912,7 +2913,7 @@ RNBRemote::HandlePacket_p (const char *p)
if (p == NULL || *p == '\0')
{
return HandlePacket_ILLFORMED ("No thread specified in p packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
}
if (!m_ctx.HasValidProcessID())
{
@ -2924,12 +2925,12 @@ RNBRemote::HandlePacket_p (const char *p)
uint32_t reg = strtoul (p + 1, &tid_cstr, 16);
if (errno != 0 && reg == 0)
{
return HandlePacket_ILLFORMED ("Could not parse register number in p packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet");
}
nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
if (tid == INVALID_NUB_THREAD)
return HandlePacket_ILLFORMED ("No thread specified in p packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
const register_map_entry_t *reg_entry;
@ -2978,7 +2979,7 @@ RNBRemote::HandlePacket_P (const char *p)
if (p == NULL || *p == '\0')
{
return HandlePacket_ILLFORMED ("Empty P packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet");
}
if (!m_ctx.HasValidProcessID())
{
@ -2995,7 +2996,7 @@ RNBRemote::HandlePacket_P (const char *p)
const char equal_char = packet.GetChar();
if (cmd_char != 'P')
return HandlePacket_ILLFORMED ("Improperly formed P packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet");
if (reg == UINT32_MAX)
return SendPacket ("E29");
@ -3022,7 +3023,7 @@ RNBRemote::HandlePacket_P (const char *p)
nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
if (tid == INVALID_NUB_THREAD)
return HandlePacket_ILLFORMED ("No thread specified in p packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
{
@ -3050,7 +3051,7 @@ RNBRemote::HandlePacket_c (const char *p)
errno = 0;
action.addr = strtoull (p + 1, NULL, 16);
if (errno != 0 && action.addr == 0)
return HandlePacket_ILLFORMED ("Could not parse address in c packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet");
}
DNBThreadResumeActions thread_actions;
@ -3082,13 +3083,13 @@ RNBRemote::HandlePacket_C (const char *p)
errno = 0;
process_signo = strtoul (p + 1, &end, 16);
if (errno != 0)
return HandlePacket_ILLFORMED ("Could not parse signal in C packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet");
else if (*end == ';')
{
errno = 0;
action.addr = strtoull (end + 1, NULL, 16);
if (errno != 0 && action.addr == 0)
return HandlePacket_ILLFORMED ("Could not parse address in C packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet");
}
}
@ -3186,14 +3187,14 @@ RNBRemote::HandlePacket_S (const char *p)
errno = 0;
action.signal = strtoul (p + 1, &end, 16);
if (errno != 0)
return HandlePacket_ILLFORMED ("Could not parse signal in S packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet");
else if (*end == ';')
{
errno = 0;
action.addr = strtoull (end + 1, NULL, 16);
if (errno != 0 && action.addr == 0)
{
return HandlePacket_ILLFORMED ("Could not parse address in S packet");
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet");
}
}
}

View File

@ -183,7 +183,7 @@ public:
rnb_err_t HandlePacket_S (const char *p);
rnb_err_t HandlePacket_v (const char *p);
rnb_err_t HandlePacket_UNIMPLEMENTED (const char *p);
rnb_err_t HandlePacket_ILLFORMED (const char *description);
rnb_err_t HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description);
rnb_err_t HandlePacket_AllocateMemory (const char *p);
rnb_err_t HandlePacket_DeallocateMemory (const char *p);