[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