[Lldb-commits] [lldb] r172869 - 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/MacOSX/MachTask.cpp

Han Ming Ong hanming at apple.com
Fri Jan 18 15:11:54 PST 2013


Author: hanming
Date: Fri Jan 18 17:11:53 2013
New Revision: 172869

URL: http://llvm.org/viewvc/llvm-project?rev=172869&view=rev
Log:
<rdar://problem/12976277>

Swap in index ids for thread ids in GDBRemoteCommunicationClient. Besides dealing with the async logic, I have to take care of the situation when the inferior paused as well.

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/MacOSX/MachTask.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=172869&r1=172868&r2=172869&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Fri Jan 18 17:11:53 2013
@@ -12,6 +12,8 @@
 
 // C Includes
 // C++ Includes
+#include <sstream>
+
 // Other libraries and framework includes
 #include "llvm/ADT/Triple.h"
 #include "lldb/Interpreter/Args.h"
@@ -71,6 +73,7 @@
     m_async_packet (),
     m_async_response (),
     m_async_signal (-1),
+    m_thread_id_to_used_usec_map (),
     m_host_arch(),
     m_process_arch(),
     m_os_version_major (UINT32_MAX),
@@ -421,6 +424,99 @@
     return response_len;
 }
 
+static const char *end_delimiter = "--end--;";
+static const int end_delimiter_len = 8;
+
+std::string
+GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
+(   ProcessGDBRemote *process,
+    StringExtractorGDBRemote& profileDataExtractor
+)
+{
+    std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
+    std::stringstream final_output;
+    std::string name, value;
+
+    // Going to assuming thread_used_usec comes first, else bail out.
+    while (profileDataExtractor.GetNameColonValue(name, value))
+    {
+        if (name.compare("thread_used_id") == 0)
+        {
+            StringExtractor threadIDHexExtractor(value.c_str());
+            uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
+            
+            bool has_used_usec = false;
+            uint32_t curr_used_usec = 0;
+            std::string usec_name, usec_value;
+            uint32_t input_file_pos = profileDataExtractor.GetFilePos();
+            if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
+            {
+                if (usec_name.compare("thread_used_usec") == 0)
+                {
+                    has_used_usec = true;
+                    curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
+                }
+                else
+                {
+                    // We didn't find what we want, it is probably
+                    // an older version. Bail out.
+                    profileDataExtractor.SetFilePos(input_file_pos);
+                }
+            }
+
+            if (has_used_usec)
+            {
+                uint32_t prev_used_usec = 0;
+                std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
+                if (iterator != m_thread_id_to_used_usec_map.end())
+                {
+                    prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
+                }
+                
+                uint32_t real_used_usec = curr_used_usec - prev_used_usec;
+                // A good first time record is one that runs for at least 0.25 sec
+                bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
+                bool good_subsequent_time = (prev_used_usec > 0) &&
+                    ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
+                
+                if (good_first_time || good_subsequent_time)
+                {
+                    // We try to avoid doing too many index id reservation,
+                    // resulting in fast increase of index ids.
+                    
+                    final_output << name << ":";
+                    int32_t index_id = process->AssignIndexIDToThread(thread_id);
+                    final_output << index_id << ";";
+                    
+                    final_output << usec_name << ":" << usec_value << ";";
+                }
+                else
+                {
+                    // Skip past 'thread_used_name'.
+                    std::string local_name, local_value;
+                    profileDataExtractor.GetNameColonValue(local_name, local_value);
+                }
+                
+                // Store current time as previous time so that they can be compared later.
+                new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
+            }
+            else
+            {
+                // Bail out and use old string.
+                final_output << name << ":" << value << ";";
+            }
+        }
+        else
+        {
+            final_output << name << ":" << value << ";";
+        }
+    }
+    final_output << end_delimiter;
+    m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
+    
+    return final_output.str();
+}
+
 StateType
 GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
 (
@@ -654,10 +750,29 @@
                 case 'A':
                     // Async miscellaneous reply. Right now, only profile data is coming through this channel.
                     {
-                        const std::string& profile_data = response.GetStringRef();
-                        const char *data_cstr = profile_data.c_str();
-                        data_cstr++; // Move beyond 'A'
-                        process->BroadcastAsyncProfileData (data_cstr, profile_data.size()-1);
+                        std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
+                        if (m_partial_profile_data.length() > 0)
+                        {
+                            m_partial_profile_data.append(input);
+                            input = m_partial_profile_data;
+                            m_partial_profile_data.clear();
+                        }
+                        
+                        size_t found, pos = 0, len = input.length();
+                        while ((found = input.find(end_delimiter, pos)) != std::string::npos)
+                        {
+                            StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
+                            const std::string& profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
+                            process->BroadcastAsyncProfileData (profile_data.c_str(), profile_data.length());
+                            
+                            pos = found + end_delimiter_len;
+                        }
+                        
+                        if (pos < len)
+                        {
+                            // Last incomplete chunk.
+                            m_partial_profile_data = input.substr(pos);
+                        }
                     }
                     break;
 

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=172869&r1=172868&r2=172869&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Fri Jan 18 17:11:53 2013
@@ -354,6 +354,11 @@
     {
         return m_interrupt_sent;
     }
+    
+    std::string
+    HarmonizeThreadIdsForProfileData (ProcessGDBRemote *process,
+                                      StringExtractorGDBRemote &inputStringExtractor);
+    
 protected:
 
     bool
@@ -407,6 +412,8 @@
     StringExtractorGDBRemote m_async_response;
     int m_async_signal; // We were asked to deliver a signal to the inferior process.
     bool m_interrupt_sent;
+    std::string m_partial_profile_data;
+    std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
     
     lldb_private::ArchSpec m_host_arch;
     lldb_private::ArchSpec m_process_arch;

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=172869&r1=172868&r2=172869&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Jan 18 17:11:53 2013
@@ -3208,7 +3208,13 @@
                 result.SetStatus (eReturnStatusSuccessFinishResult);
                 Stream &output_strm = result.GetOutputStream();
                 output_strm.Printf ("  packet: %s\n", packet_cstr);
-                const std::string &response_str = response.GetStringRef();
+                std::string &response_str = response.GetStringRef();
+                
+                if (strcmp(packet_cstr, "qGetProfileData") == 0)
+                {
+                    response_str = process->GetGDBRemote().HarmonizeThreadIdsForProfileData(process, response);
+                }
+
                 if (response_str.empty())
                     output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
                 else

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp?rev=172869&r1=172868&r2=172869&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp Fri Jan 18 17:11:53 2013
@@ -340,6 +340,7 @@
         
         for (int i=0; i<num_threads; i++) {
             profile_data_stream << "thread_used_id:" << std::hex << threads_id[i] << std::dec << ';';
+            profile_data_stream << "thread_used_usec:" << threads_used_usec[i] << ';';
             
             profile_data_stream << "thread_used_name:";
             int len = threads_name[i].size();
@@ -356,8 +357,6 @@
                 profile_data_stream << DECIMAL;
             }
             profile_data_stream << ';';
-            
-            profile_data_stream << "thread_used_usec:" << threads_used_usec[i] << ';';
         }
         
         profile_data_stream << "wired:" << vm_stats.wire_count * vm_page_size << ';';





More information about the lldb-commits mailing list