[Lldb-commits] [lldb] r240988 - More packet reduction when debugging with GDB server.

Greg Clayton gclayton at apple.com
Mon Jun 29 13:08:51 PDT 2015


Author: gclayton
Date: Mon Jun 29 15:08:51 2015
New Revision: 240988

URL: http://llvm.org/viewvc/llvm-project?rev=240988&view=rev
Log:
More packet reduction when debugging with GDB server.

- Avoid sending the qfThreadInfo, qsThreadInfo packets if we have a stop reply packet with the threads already (save 2 round trip packets)
- Include the qname, qserial and qkind in the JSON info
- Report the qname, qserial and qkind to the thread so it can cache it to avoid many packets on MacOSX and iOS
- Don't clear all discoverable settings when we exec, just the ones we need to saves 1-5 packets for each exec.


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/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp

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=240988&r1=240987&r2=240988&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Mon Jun 29 15:08:51 2015
@@ -140,7 +140,7 @@ GDBRemoteCommunicationClient::~GDBRemote
 bool
 GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
 {
-    ResetDiscoverableSettings();
+    ResetDiscoverableSettings(false);
 
     // Start the read thread after we send the handshake ack since if we
     // fail to send the handshake ack, there is no reason to continue...
@@ -334,60 +334,64 @@ GDBRemoteCommunicationClient::GetSyncThr
 
 
 void
-GDBRemoteCommunicationClient::ResetDiscoverableSettings()
+GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec)
 {
-    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;
-    m_supports_vCont_S = eLazyBoolCalculate;
-    m_supports_p = eLazyBoolCalculate;
-    m_supports_x = eLazyBoolCalculate;
-    m_supports_QSaveRegisterState = eLazyBoolCalculate;
-    m_qHostInfo_is_valid = eLazyBoolCalculate;
-    m_curr_pid_is_valid = eLazyBoolCalculate;
+    if (did_exec == false)
+    {
+        // Hard reset everything, this is when we first connect to a GDB server
+        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;
+        m_supports_vCont_S = eLazyBoolCalculate;
+        m_supports_p = eLazyBoolCalculate;
+        m_supports_x = eLazyBoolCalculate;
+        m_supports_QSaveRegisterState = eLazyBoolCalculate;
+        m_qHostInfo_is_valid = eLazyBoolCalculate;
+        m_curr_pid_is_valid = eLazyBoolCalculate;
+        m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
+        m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
+        m_supports_memory_region_info = eLazyBoolCalculate;
+        m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
+        m_attach_or_wait_reply = eLazyBoolCalculate;
+        m_avoid_g_packets = eLazyBoolCalculate;
+        m_supports_qXfer_auxv_read = eLazyBoolCalculate;
+        m_supports_qXfer_libraries_read = eLazyBoolCalculate;
+        m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
+        m_supports_qXfer_features_read = eLazyBoolCalculate;
+        m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
+        m_supports_qProcessInfoPID = true;
+        m_supports_qfProcessInfo = true;
+        m_supports_qUserName = true;
+        m_supports_qGroupName = true;
+        m_supports_qThreadStopInfo = true;
+        m_supports_z0 = true;
+        m_supports_z1 = true;
+        m_supports_z2 = true;
+        m_supports_z3 = true;
+        m_supports_z4 = true;
+        m_supports_QEnvironment = true;
+        m_supports_QEnvironmentHexEncoded = true;
+        m_supports_qSymbol = true;
+        m_host_arch.Clear();
+        m_os_version_major = UINT32_MAX;
+        m_os_version_minor = UINT32_MAX;
+        m_os_version_update = UINT32_MAX;
+        m_os_build.clear();
+        m_os_kernel.clear();
+        m_hostname.clear();
+        m_gdb_server_name.clear();
+        m_gdb_server_version = UINT32_MAX;
+        m_default_packet_timeout = 0;
+        m_max_packet_size = 0;
+    }
+
+    // These flags should be reset when we first connect to a GDB server
+    // and when our inferior process execs
     m_qProcessInfo_is_valid = eLazyBoolCalculate;
-    m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
-    m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
-    m_supports_memory_region_info = eLazyBoolCalculate;
-    m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
-    m_attach_or_wait_reply = eLazyBoolCalculate;
-    m_avoid_g_packets = eLazyBoolCalculate;
-    m_supports_qXfer_auxv_read = eLazyBoolCalculate;
-    m_supports_qXfer_libraries_read = eLazyBoolCalculate;
-    m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
-    m_supports_qXfer_features_read = eLazyBoolCalculate;
-    m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
-
-    m_supports_qProcessInfoPID = true;
-    m_supports_qfProcessInfo = true;
-    m_supports_qUserName = true;
-    m_supports_qGroupName = true;
-    m_supports_qThreadStopInfo = true;
-    m_supports_z0 = true;
-    m_supports_z1 = true;
-    m_supports_z2 = true;
-    m_supports_z3 = true;
-    m_supports_z4 = true;
-    m_supports_QEnvironment = true;
-    m_supports_QEnvironmentHexEncoded = true;
-    m_supports_qSymbol = true;
-    
-    m_host_arch.Clear();
     m_process_arch.Clear();
-    m_os_version_major = UINT32_MAX;
-    m_os_version_minor = UINT32_MAX;
-    m_os_version_update = UINT32_MAX;
-    m_os_build.clear();
-    m_os_kernel.clear();
-    m_hostname.clear();
-    m_gdb_server_name.clear();
-    m_gdb_server_version = UINT32_MAX;
-    m_default_packet_timeout = 0;
-
-    m_max_packet_size = 0;
 }
 
 void

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=240988&r1=240987&r2=240988&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Mon Jun 29 15:08:51 2015
@@ -320,7 +320,7 @@ public:
     GetSyncThreadStateSupported();
     
     void
-    ResetDiscoverableSettings();
+    ResetDiscoverableSettings (bool did_exec);
 
     bool
     GetHostInfo (bool force = false);

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=240988&r1=240987&r2=240988&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Mon Jun 29 15:08:51 2015
@@ -1721,10 +1721,85 @@ ProcessGDBRemote::ClearThreadIDList ()
     m_thread_ids.clear();
 }
 
+size_t
+ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue (std::string &value)
+{
+    m_thread_ids.clear();
+    size_t comma_pos;
+    lldb::tid_t tid;
+    while ((comma_pos = value.find(',')) != std::string::npos)
+    {
+        value[comma_pos] = '\0';
+        // thread in big endian hex
+        tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+        if (tid != LLDB_INVALID_THREAD_ID)
+            m_thread_ids.push_back (tid);
+        value.erase(0, comma_pos + 1);
+    }
+    tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+    if (tid != LLDB_INVALID_THREAD_ID)
+        m_thread_ids.push_back (tid);
+    return m_thread_ids.size();
+}
+
 bool
 ProcessGDBRemote::UpdateThreadIDList ()
 {
     Mutex::Locker locker(m_thread_list_real.GetMutex());
+
+    if (m_threads_info_sp)
+    {
+        // If we have the JSON threads info, we can get the thread list from that
+        StructuredData::Array *thread_infos = m_threads_info_sp->GetAsArray();
+        if (thread_infos && thread_infos->GetSize() > 0)
+        {
+            m_thread_ids.clear();
+            thread_infos->ForEach([this](StructuredData::Object* object) -> bool {
+                StructuredData::Dictionary *thread_dict = object->GetAsDictionary();
+                if (thread_dict)
+                {
+                    // Set the thread stop info from the JSON dictionary
+                    SetThreadStopInfo (thread_dict);
+                    lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+                    if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid))
+                        m_thread_ids.push_back(tid);
+                }
+                return true; // Keep iterating through all thread_info objects
+            });
+        }
+        if (!m_thread_ids.empty())
+            return true;
+    }
+    else
+    {
+        // See if we can get the thread IDs from the current stop reply packets
+        // that might contain a "threads" key/value pair
+
+        // Lock the thread stack while we access it
+        Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
+        // Get the number of stop packets on the stack
+        int nItems = m_stop_packet_stack.size();
+        // Iterate over them
+        for (int i = 0; i < nItems; i++)
+        {
+            // Get the thread stop info
+            StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i];
+            const std::string &stop_info_str = stop_info.GetStringRef();
+            const size_t threads_pos = stop_info_str.find(";threads:");
+            if (threads_pos != std::string::npos)
+            {
+                const size_t start = threads_pos + strlen(";threads:");
+                const size_t end = stop_info_str.find(';', start);
+                if (end != std::string::npos)
+                {
+                    std::string value = stop_info_str.substr(start, end - start);
+                    if (UpdateThreadIDsFromStopReplyThreadsValue(value))
+                        return true;
+                }
+            }
+        }
+    }
+
     bool sequence_mutex_unavailable = false;
     m_gdb_comm.GetCurrentThreadIDs (m_thread_ids, sequence_mutex_unavailable);
     if (sequence_mutex_unavailable)
@@ -1839,7 +1914,11 @@ ProcessGDBRemote::SetThreadStopInfo (lld
                                      const std::string &description,
                                      uint32_t exc_type,
                                      const std::vector<addr_t> &exc_data,
-                                     addr_t thread_dispatch_qaddr)
+                                     addr_t thread_dispatch_qaddr,
+                                     bool queue_vars_valid, // Set to true if queue_name, queue_kind and queue_serial are valid
+                                     std::string &queue_name,
+                                     QueueKind queue_kind,
+                                     uint64_t queue_serial)
 {
     ThreadSP thread_sp;
     if (tid != LLDB_INVALID_THREAD_ID)
@@ -1864,7 +1943,7 @@ ProcessGDBRemote::SetThreadStopInfo (lld
         {
             ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
             gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
-            
+
             for (const auto &pair : expedited_register_map)
             {
                 StringExtractor reg_value_extractor;
@@ -1877,6 +1956,13 @@ ProcessGDBRemote::SetThreadStopInfo (lld
             thread_sp->SetName (thread_name.empty() ? NULL : thread_name.c_str());
 
             gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
+            // Check if the GDB server was able to provide the queue name, kind and serial number
+            if (queue_vars_valid)
+                gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind, queue_serial);
+            else
+                gdb_thread->ClearQueueInfo();
+
+
             if (exc_type != 0)
             {
                 const size_t exc_data_size = exc_data.size();
@@ -2031,6 +2117,9 @@ ProcessGDBRemote::SetThreadStopInfo (Str
     static ConstString g_key_metype("metype");
     static ConstString g_key_medata("medata");
     static ConstString g_key_qaddr("qaddr");
+    static ConstString g_key_queue_name("qname");
+    static ConstString g_key_queue_kind("qkind");
+    static ConstString g_key_queue_serial("qserial");
     static ConstString g_key_registers("registers");
     static ConstString g_key_memory("memory");
     static ConstString g_key_address("address");
@@ -2048,9 +2137,27 @@ ProcessGDBRemote::SetThreadStopInfo (Str
     std::vector<addr_t> exc_data;
     addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
     ExpeditedRegisterMap expedited_register_map;
+    bool queue_vars_valid = false;
+    std::string queue_name;
+    QueueKind queue_kind = eQueueKindUnknown;
+    uint64_t queue_serial = 0;
     // Iterate through all of the thread dictionary key/value pairs from the structured data dictionary
 
-    thread_dict->ForEach([this, &tid, &expedited_register_map, &thread_name, &signo, &reason, &description, &exc_type, &exc_data, &thread_dispatch_qaddr](ConstString key, StructuredData::Object* object) -> bool
+    thread_dict->ForEach([this,
+                          &tid,
+                          &expedited_register_map,
+                          &thread_name,
+                          &signo,
+                          &reason,
+                          &description,
+                          &exc_type,
+                          &exc_data,
+                          &thread_dispatch_qaddr,
+                          &queue_vars_valid,
+                          &queue_name,
+                          &queue_kind,
+                          &queue_serial]
+                          (ConstString key, StructuredData::Object* object) -> bool
     {
         if (key == g_key_tid)
         {
@@ -2082,6 +2189,31 @@ ProcessGDBRemote::SetThreadStopInfo (Str
         {
             thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
         }
+        else if (key == g_key_queue_name)
+        {
+            queue_vars_valid = true;
+            queue_name = std::move(object->GetStringValue());
+        }
+        else if (key == g_key_queue_kind)
+        {
+            std::string queue_kind_str = object->GetStringValue();
+            if (queue_kind_str == "serial")
+            {
+                queue_vars_valid = true;
+                queue_kind = eQueueKindSerial;
+            }
+            else if (queue_kind_str == "concurrent")
+            {
+                queue_vars_valid = true;
+                queue_kind = eQueueKindConcurrent;
+            }
+        }
+        else if (key == g_key_queue_serial)
+        {
+            queue_serial = object->GetIntegerValue(0);
+            if (queue_serial != 0)
+                queue_vars_valid = true;
+        }
         else if (key == g_key_reason)
         {
             reason = std::move(object->GetStringValue());
@@ -2148,7 +2280,11 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                        description,
                        exc_type,
                        exc_data,
-                       thread_dispatch_qaddr);
+                       thread_dispatch_qaddr,
+                       queue_vars_valid,
+                       queue_name,
+                       queue_kind,
+                       queue_serial);
 
     return eStateExited;
 }
@@ -2265,16 +2401,22 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                 }
                 else if (key.compare("qkind") == 0)
                 {
-                    queue_vars_valid = true;
                     if (value == "serial")
+                    {
+                        queue_vars_valid = true;
                         queue_kind = eQueueKindSerial;
+                    }
                     else if (value == "concurrent")
+                    {
+                        queue_vars_valid = true;
                         queue_kind = eQueueKindConcurrent;
+                    }
                 }
                 else if (key.compare("qserial") == 0)
                 {
-                    queue_vars_valid = true;
                     queue_serial = StringConvert::ToUInt64 (value.c_str(), 0, 0);
+                    if (queue_serial != 0)
+                        queue_vars_valid = true;
                 }
                 else if (key.compare("reason") == 0)
                 {
@@ -2338,7 +2480,11 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                                                     description,
                                                     exc_type,
                                                     exc_data,
-                                                    thread_dispatch_qaddr);
+                                                    thread_dispatch_qaddr,
+                                                    queue_vars_valid,
+                                                    queue_name,
+                                                    queue_kind,
+                                                    queue_serial);
 
             // If the response is old style 'S' packet which does not provide us with thread information
             // then update the thread list and choose the first one.
@@ -2681,7 +2827,7 @@ ProcessGDBRemote::SetLastStopPacket (con
         m_thread_list_real.Clear();
         m_thread_list.Clear();
         BuildDynamicRegisterInfo (true);
-        m_gdb_comm.ResetDiscoverableSettings();
+        m_gdb_comm.ResetDiscoverableSettings (did_exec);
     }
 
     // Scope the lock

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=240988&r1=240987&r2=240988&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Mon Jun 29 15:08:51 2015
@@ -329,6 +329,9 @@ protected:
     bool
     CalculateThreadStopInfo (ThreadGDBRemote *thread);
 
+    size_t
+    UpdateThreadIDsFromStopReplyThreadsValue (std::string &value);
+
     //------------------------------------------------------------------
     /// Broadcaster event bits definitions.
     //------------------------------------------------------------------
@@ -402,7 +405,11 @@ protected:
                        const std::string &description,
                        uint32_t exc_type,
                        const std::vector<lldb::addr_t> &exc_data,
-                       lldb::addr_t thread_dispatch_qaddr);
+                       lldb::addr_t thread_dispatch_qaddr,
+                       bool queue_vars_valid,
+                       std::string &queue_name,
+                       lldb::QueueKind queue_kind,
+                       uint64_t queue_serial);
 
     void
     HandleStopReplySequence ();

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=240988&r1=240987&r2=240988&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Mon Jun 29 15:08:51 2015
@@ -5029,7 +5029,26 @@ RNBRemote::HandlePacket_jThreadsInfo (co
             if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
             {
                 if (thread_ident_info.dispatch_qaddr != 0)
+                {
                     thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr);
+
+                    const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets();
+                    if (dispatch_queue_offsets)
+                    {
+                        std::string queue_name;
+                        uint64_t queue_width = 0;
+                        uint64_t queue_serialnum = 0;
+                        dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, queue_name, queue_width, queue_serialnum);
+                        if (!queue_name.empty())
+                            thread_dict_sp->AddStringItem("qname", queue_name);
+                        if (queue_width == 1)
+                            thread_dict_sp->AddStringItem("qkind", "serial");
+                        else if (queue_width > 1)
+                            thread_dict_sp->AddStringItem("qkind", "concurrent");
+                        if (queue_serialnum > 0)
+                            thread_dict_sp->AddIntegerItem("qserial", queue_serialnum);
+                    }
+                }
             }
             DNBRegisterValue reg_value;
 





More information about the lldb-commits mailing list