[Lldb-commits] [lldb] r154380 - in /lldb/trunk: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp tools/debugserver/source/RNBRemote.cpp tools/debugserver/source/RNBRemote.h
Greg Clayton
gclayton at apple.com
Mon Apr 9 20:22:03 PDT 2012
Author: gclayton
Date: Mon Apr 9 22:22:03 2012
New Revision: 154380
URL: http://llvm.org/viewvc/llvm-project?rev=154380&view=rev
Log:
Added a new packet to our GDB remote protocol:
QListThreadsInStopReply
This GDB remote query command can enable added a "threads" key/value pair to all stop reply packets so that we always get a list of all threads in each stop reply packet. It increases performance if enabled (the reply to the "QListThreadsInStopReply" is "OK") by saving us from sending to command/reply pairs (the "qfThreadInfo" and "qsThreadInfo" packets), and also helps us keep the current process state up to date.
Modified:
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/trunk/tools/debugserver/source/RNBRemote.cpp
lldb/trunk/tools/debugserver/source/RNBRemote.h
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=154380&r1=154379&r2=154380&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Mon Apr 9 22:22:03 2012
@@ -38,6 +38,7 @@
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 @@
}
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;
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=154380&r1=154379&r2=154380&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Mon Apr 9 22:22:03 2012
@@ -71,6 +71,9 @@
void
QueryNoAckModeSupported ();
+ void
+ GetListThreadsInStopReplySupported ();
+
bool
SendAsyncSignal (int signo);
@@ -335,6 +338,7 @@
//------------------------------------------------------------------
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;
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=154380&r1=154379&r2=154380&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Mon Apr 9 22:22:03 2012
@@ -704,6 +704,7 @@
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 @@
{
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)
Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=154380&r1=154379&r2=154380&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Mon Apr 9 22:22:03 2012
@@ -76,8 +76,9 @@
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 @@
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 @@
}
-/* `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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
-/* `p XX'
+/* 'p XX'
print the contents of register X */
rnb_err_t
@@ -3147,7 +3198,7 @@
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 @@
return SendPacket ("OK");
}
-/* `c [addr]'
+/* 'c [addr]'
Continue, optionally from a specified address. */
rnb_err_t
@@ -3311,7 +3362,7 @@
}
-/* `C sig [;addr]'
+/* 'C sig [;addr]'
Resume with signal sig, optionally at address addr. */
rnb_err_t
@@ -3365,7 +3416,7 @@
return rnb_success;
}
-/* `k'
+/* 'k'
Kill the inferior process. */
rnb_err_t
@@ -3387,7 +3438,7 @@
return rnb_success;
}
-/* `s'
+/* 's'
Step the inferior process. */
rnb_err_t
@@ -3416,7 +3467,7 @@
return rnb_success;
}
-/* `S sig [;addr]'
+/* 'S sig [;addr]'
Step with signal sig, optionally at address addr. */
rnb_err_t
Modified: lldb/trunk/tools/debugserver/source/RNBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.h?rev=154380&r1=154379&r2=154380&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.h Mon Apr 9 22:22:03 2012
@@ -106,6 +106,7 @@
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 @@
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 @@
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
More information about the lldb-commits
mailing list