summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp19
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp6
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp81
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.h12
5 files changed, 100 insertions, 22 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 4fbfa982e0d..16a339c86c2 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -38,6 +38,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform),
m_supports_not_sending_acks (eLazyBoolCalculate),
m_supports_thread_suffix (eLazyBoolCalculate),
+ m_supports_threads_in_stop_reply (eLazyBoolCalculate),
m_supports_vCont_all (eLazyBoolCalculate),
m_supports_vCont_any (eLazyBoolCalculate),
m_supports_vCont_c (eLazyBoolCalculate),
@@ -114,10 +115,28 @@ GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
}
void
+GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
+{
+ if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
+ {
+ m_supports_threads_in_stop_reply = eLazyBoolNo;
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false))
+ {
+ if (response.IsOKResponse())
+ m_supports_threads_in_stop_reply = eLazyBoolYes;
+ }
+ }
+}
+
+
+void
GDBRemoteCommunicationClient::ResetDiscoverableSettings()
{
m_supports_not_sending_acks = eLazyBoolCalculate;
m_supports_thread_suffix = eLazyBoolCalculate;
+ m_supports_threads_in_stop_reply = eLazyBoolCalculate;
m_supports_vCont_c = eLazyBoolCalculate;
m_supports_vCont_C = eLazyBoolCalculate;
m_supports_vCont_s = eLazyBoolCalculate;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 92f90c63702..c7ac21d83ad 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -71,6 +71,9 @@ public:
void
QueryNoAckModeSupported ();
+ void
+ GetListThreadsInStopReplySupported ();
+
bool
SendAsyncSignal (int signo);
@@ -335,6 +338,7 @@ protected:
//------------------------------------------------------------------
lldb_private::LazyBool m_supports_not_sending_acks;
lldb_private::LazyBool m_supports_thread_suffix;
+ lldb_private::LazyBool m_supports_threads_in_stop_reply;
lldb_private::LazyBool m_supports_vCont_all;
lldb_private::LazyBool m_supports_vCont_any;
lldb_private::LazyBool m_supports_vCont_c;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index e207ebd9153..035c6128db9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -704,6 +704,7 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
m_gdb_comm.ResetDiscoverableSettings();
m_gdb_comm.QueryNoAckModeSupported ();
m_gdb_comm.GetThreadSuffixSupported ();
+ m_gdb_comm.GetListThreadsInStopReplySupported ();
m_gdb_comm.GetHostInfo ();
m_gdb_comm.GetVContSupported ('c');
return error;
@@ -1262,8 +1263,9 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
{
Mutex::Locker locker(m_thread_ids_mutex);
m_thread_ids.clear();
- // A comma separated list of all threads in the current process including
- // the thread for this stop reply packet
+ // A comma separated list of all threads in the current
+ // process that includes the thread for this stop reply
+ // packet
size_t comma_pos;
lldb::tid_t tid;
while ((comma_pos = value.find(',')) != std::string::npos)
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index ef4a26683f2..e776cef689e 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -76,8 +76,9 @@ RNBRemote::RNBRemote () :
m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
m_extended_mode(false),
m_noack_mode(false),
+ m_use_native_regs (false),
m_thread_suffix_supported (false),
- m_use_native_regs (false)
+ m_list_threads_in_stop_reply (false)
{
DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
CreatePacketTable ();
@@ -183,6 +184,7 @@ RNBRemote::CreatePacketTable ()
t.push_back (Packet (set_stdout, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDOUT:", "Set the standard output for a process to be launched with the 'A' packet"));
t.push_back (Packet (set_stderr, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDERR:", "Set the standard error for a process to be launched with the 'A' packet"));
t.push_back (Packet (set_working_dir, &RNBRemote::HandlePacket_QSetWorkingDir , NULL, "QSetWorkingDir:", "Set the working directory for a process to be launched with the 'A' packet"));
+ t.push_back (Packet (set_list_threads_in_stop_reply,&RNBRemote::HandlePacket_QListThreadsInStopReply , NULL, "QListThreadsInStopReply", "Set if the 'threads' key should be added to the stop reply packets with a list of all thread IDs."));
// t.push_back (Packet (pass_signals_to_inferior, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior"));
t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process."));
t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
@@ -1128,12 +1130,12 @@ RNBRemote::NotifyThatProcessStopped (void)
}
-/* `A arglen,argnum,arg,...'
+/* 'A arglen,argnum,arg,...'
Update the inferior context CTX with the program name and arg
list.
The documentation for this packet is underwhelming but my best reading
of this is that it is a series of (len, position #, arg)'s, one for
- each argument with "arg" ``hex encoded'' (two 0-9a-f chars?).
+ each argument with "arg" hex encoded (two 0-9a-f chars?).
Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either
is sufficient to get around the "," position separator escape issue.
@@ -1223,7 +1225,7 @@ RNBRemote::HandlePacket_A (const char *p)
return rnb_success;
}
-/* `H c t'
+/* 'H c t'
Set the thread for subsequent actions; 'c' for step/continue ops,
'g' for other ops. -1 means all threads, 0 means any thread. */
@@ -1868,6 +1870,28 @@ RNBRemote::HandlePacket_QSetWorkingDir (const char *p)
return SendPacket ("E60"); // Already had a process, too late to set working dir
}
+rnb_err_t
+RNBRemote::HandlePacket_QListThreadsInStopReply (const char *p)
+{
+ // If this packet is received, it allows us to send an extra key/value
+ // pair in the stop reply packets where we will list all of the thread IDs
+ // separated by commas:
+ //
+ // "threads:10a,10b,10c;"
+ //
+ // This will get included in the stop reply packet as something like:
+ //
+ // "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;"
+ //
+ // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and
+ // speed things up a bit.
+ //
+ // Send the OK packet first so the correct checksum is appended...
+ rnb_err_t result = SendPacket ("OK");
+ m_list_threads_in_stop_reply = true;
+ return result;
+}
+
rnb_err_t
RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
@@ -2118,6 +2142,33 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
if (thread_ident_info.dispatch_qaddr != 0)
ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
}
+
+ // If a 'QListThreadsInStopReply' was sent to enable this feature, we
+ // will send all thread IDs back in the "threads" key whose value is
+ // a listc of hex thread IDs separated by commas:
+ // "threads:10a,10b,10c;"
+ // This will save the debugger from having to send a pair of qfThreadInfo
+ // and qsThreadInfo packets, but it also might take a lot of room in the
+ // stop reply packet, so it must be enabled only on systems where there
+ // are no limits on packet lengths.
+
+ if (m_list_threads_in_stop_reply)
+ {
+ const nub_size_t numthreads = DNBProcessGetNumThreads (pid);
+ if (numthreads > 0)
+ {
+ ostrm << std::hex << "threads:";
+ for (nub_size_t i = 0; i < numthreads; ++i)
+ {
+ nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
+ if (i > 0)
+ ostrm << ',';
+ ostrm << std::hex << th;
+ }
+ ostrm << ';';
+ }
+ }
+
if (g_num_reg_entries == 0)
InitializeRegisters ();
@@ -2145,7 +2196,7 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
return SendPacket("E51");
}
-/* `?'
+/* '?'
The stop reply packet - tell gdb what the status of the inferior is.
Often called the questionmark_packet. */
@@ -2401,7 +2452,7 @@ RNBRemote::HandlePacket_X (const char *p)
return SendPacket ("OK");
}
-/* `g' -- read registers
+/* 'g' -- read registers
Get the contents of the registers for the current thread,
send them to gdb.
Should the setting of the Hg packet determine which thread's registers
@@ -2449,7 +2500,7 @@ RNBRemote::HandlePacket_g (const char *p)
return SendPacket (ostrm.str ());
}
-/* `G XXX...' -- write registers
+/* 'G XXX...' -- write registers
How is the thread for these specified, beyond "the current thread"?
Does gdb actually use the Hg packet to set this? */
@@ -2809,7 +2860,7 @@ RNBRemote::HandlePacket_v (const char *p)
return HandlePacket_UNIMPLEMENTED(p);
}
-/* `T XX' -- status of thread
+/* 'T XX' -- status of thread
Check if the specified thread is alive.
The thread number is in hex? */
@@ -3082,7 +3133,7 @@ RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
}
-/* `p XX'
+/* 'p XX'
print the contents of register X */
rnb_err_t
@@ -3147,7 +3198,7 @@ RNBRemote::HandlePacket_p (const char *p)
return SendPacket (ostrm.str());
}
-/* `Pnn=rrrrr'
+/* 'Pnn=rrrrr'
Set register number n to value r.
n and r are hex strings. */
@@ -3212,7 +3263,7 @@ RNBRemote::HandlePacket_P (const char *p)
return SendPacket ("OK");
}
-/* `c [addr]'
+/* 'c [addr]'
Continue, optionally from a specified address. */
rnb_err_t
@@ -3311,7 +3362,7 @@ RNBRemote::HandlePacket_MemoryRegionInfo (const char *p)
}
-/* `C sig [;addr]'
+/* 'C sig [;addr]'
Resume with signal sig, optionally at address addr. */
rnb_err_t
@@ -3365,7 +3416,7 @@ RNBRemote::HandlePacket_D (const char *p)
return rnb_success;
}
-/* `k'
+/* 'k'
Kill the inferior process. */
rnb_err_t
@@ -3387,7 +3438,7 @@ RNBRemote::HandlePacket_stop_process (const char *p)
return rnb_success;
}
-/* `s'
+/* 's'
Step the inferior process. */
rnb_err_t
@@ -3416,7 +3467,7 @@ RNBRemote::HandlePacket_s (const char *p)
return rnb_success;
}
-/* `S sig [;addr]'
+/* 'S sig [;addr]'
Step with signal sig, optionally at address addr. */
rnb_err_t
diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h
index 25d04a35eeb..489a025fe60 100644
--- a/lldb/tools/debugserver/source/RNBRemote.h
+++ b/lldb/tools/debugserver/source/RNBRemote.h
@@ -106,6 +106,7 @@ public:
set_stdout, // 'QSetSTDOUT:'
set_stderr, // 'QSetSTDERR:'
set_working_dir, // 'QSetWorkingDir:'
+ set_list_threads_in_stop_reply, // 'QListThreadsInStopReply:'
memory_region_info, // 'qMemoryRegionInfo:'
allocate_memory, // '_M'
deallocate_memory, // '_m'
@@ -177,6 +178,7 @@ public:
rnb_err_t HandlePacket_QEnvironment (const char *p);
rnb_err_t HandlePacket_QEnvironmentHexEncoded (const char *p);
rnb_err_t HandlePacket_QLaunchArch (const char *p);
+ rnb_err_t HandlePacket_QListThreadsInStopReply (const char *p);
rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p);
rnb_err_t HandlePacket_last_signal (const char *p);
rnb_err_t HandlePacket_m (const char *p);
@@ -328,15 +330,15 @@ protected:
BreakpointMap m_breakpoints;
BreakpointMap m_watchpoints;
uint32_t m_max_payload_size; // the maximum sized payload we should send to gdb
- bool m_extended_mode:1, // are we in extended mode?
- m_noack_mode:1, // are we in no-ack mode?
- m_noack_mode_just_enabled:1, // Did we just enable this and need to compute one more checksum?
- m_use_native_regs:1, // Use native registers by querying DNB layer for register definitions?
- m_thread_suffix_supported:1; // Set to true if the 'p', 'P', 'g', and 'G' packets should be prefixed with the thread ID and colon:
+ bool m_extended_mode; // are we in extended mode?
+ bool m_noack_mode; // are we in no-ack mode?
+ bool m_use_native_regs; // Use native registers by querying DNB layer for register definitions?
+ bool m_thread_suffix_supported; // Set to true if the 'p', 'P', 'g', and 'G' packets should be prefixed with the thread ID and colon:
// "$pRR;thread:TTTT;" instead of "$pRR"
// "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV"
// "$g;thread:TTTT" instead of "$g"
// "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV"
+ bool m_list_threads_in_stop_reply;
};
/* We translate the /usr/include/mach/exception_types.h exception types
OpenPOWER on IntegriCloud