[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