Fix this module to work with current packects and also to be able to figure out avera...
authorGreg Clayton <gclayton@apple.com>
Fri, 22 May 2015 23:00:59 +0000 (23:00 +0000)
committerGreg Clayton <gclayton@apple.com>
Fri, 22 May 2015 23:00:59 +0000 (23:00 +0000)
llvm-svn: 238065

lldb/examples/python/gdbremote.py

index 512162a..83af781 100755 (executable)
@@ -17,6 +17,7 @@
 #----------------------------------------------------------------------
 
 import commands
+import math
 import optparse
 import os
 import re
@@ -436,10 +437,11 @@ class Packet:
         
     def get_key_value_pairs(self):
         kvp = list()
-        key_value_pairs = string.split(self.str, ';')
-        for key_value_pair in key_value_pairs:
-            if len(key_value_pair):
-                kvp.append(string.split(key_value_pair, ':'))
+        if ';' in self.str:
+            key_value_pairs = string.split(self.str, ';')
+            for key_value_pair in key_value_pairs:
+                if len(key_value_pair):
+                    kvp.append(string.split(key_value_pair, ':'))
         return kvp
 
     def split(self, ch):
@@ -528,6 +530,7 @@ def rsp_dump_key_value_pairs(options, cmd, cmd_args, rsp):
         packet = Packet(rsp)
         key_value_pairs = packet.get_key_value_pairs()
         for key_value_pair in key_value_pairs:
+            print key_value_pair
             key = key_value_pair[0]
             value = key_value_pair[1]
             print "    %s = %s" % (key, value)
@@ -835,6 +838,7 @@ gdb_remote_commands = {
     'QStartNoAckMode'         : { 'cmd' : cmd_query_packet  , 'rsp' : rsp_ok_means_supported  , 'name' : "query if no ack mode is supported"},
     'QThreadSuffixSupported'  : { 'cmd' : cmd_query_packet  , 'rsp' : rsp_ok_means_supported  , 'name' : "query if thread suffix is supported" },
     'QListThreadsInStopReply' : { 'cmd' : cmd_query_packet  , 'rsp' : rsp_ok_means_supported  , 'name' : "query if threads in stop reply packets are supported" },
+    'QSetDetachOnError' :       { 'cmd' : cmd_query_packet  , 'rsp' : rsp_ok_means_supported  , 'name' : "query if we should detach on error" },
     'qVAttachOrWaitSupported' : { 'cmd' : cmd_query_packet  , 'rsp' : rsp_ok_means_supported  , 'name' : "query if threads attach with optional wait is supported" },
     'qHostInfo'               : { 'cmd' : cmd_query_packet  , 'rsp' : rsp_dump_key_value_pairs, 'name' : "get host information" },
     'vCont'                   : { 'cmd' : cmd_vCont         , 'rsp' : rsp_vCont               , 'name' : "extended continue command" },
@@ -844,6 +848,8 @@ gdb_remote_commands = {
     'qsThreadInfo'            : { 'cmd' : cmd_qThreadInfo   , 'rsp' : rsp_qThreadInfo         , 'name' : "get current thread list" },
     'qShlibInfoAddr'          : { 'cmd' : cmd_query_packet  , 'rsp' : rsp_hex_big_endian      , 'name' : "get shared library info address" },
     'qMemoryRegionInfo'       : { 'cmd' : cmd_mem_rgn_info  , 'rsp' : rsp_dump_key_value_pairs, 'name' : "get memory region information" },
+    'qProcessInfo'            : { 'cmd' : cmd_query_packet  , 'rsp' : rsp_dump_key_value_pairs, 'name' : "get process info" },
+    'qSupported'              : { 'cmd' : cmd_query_packet  , 'rsp' : rsp_ok_means_supported  , 'name' : "query supported" },
     'm'                       : { 'cmd' : cmd_read_memory   , 'rsp' : rsp_memory_bytes        , 'name' : "read memory" },
     'M'                       : { 'cmd' : cmd_write_memory  , 'rsp' : rsp_ok_means_success    , 'name' : "write memory" },
     '_M'                      : { 'cmd' : cmd_alloc_memory  , 'rsp' : rsp_alloc_memory        , 'name' : "allocate memory" },
@@ -856,6 +862,21 @@ gdb_remote_commands = {
     'Z'                       : { 'cmd' : cmd_bp            , 'rsp' : rsp_ok_means_success    , 'name' : "set breakpoint or watchpoint" },
     'k'                       : { 'cmd' : cmd_kill          , 'rsp' : rsp_stop_reply          , 'name' : "kill process" },
 }
+
+def calculate_mean_and_standard_deviation(floats):
+    sum = 0.0
+    count = len(floats)
+    for f in floats:
+        sum += f
+    mean =  sum / count
+    accum = 0.0
+    for f in floats:
+        delta = f - mean
+        accum += delta * delta
+        
+    std_dev = math.sqrt(accum / (count-1));
+    return (mean, std_dev)
+    
 def parse_gdb_log_file(file, options):
     '''Parse a GDB log file that was generated by enabling logging with:
     (lldb) log enable --threadsafe --timestamp --file <FILE> gdb-remote packets
@@ -878,6 +899,7 @@ def parse_gdb_log_file(file, options):
     last_time = 0.0
     packet_send_time = 0.0
     packet_total_times = {}
+    packet_times = []
     packet_count = {}
     file = open(file)
     lines = file.read().splitlines()
@@ -885,29 +907,26 @@ def parse_gdb_log_file(file, options):
     last_command_args = None
     last_command_packet = None
     for line in lines:
-        packet_name = None
         m = packet_transmit_name_regex.search(line)
         is_command = False
+        direction = None
         if m:
             direction = m.group('direction')
             is_command = direction == 'send'
             packet = m.group('packet')
             sys.stdout.write(options.colors.green())
-            if options.quiet:
-                if is_command:
-                    print '-->', packet
-                else:
-                    print '<--', packet
-            else:
+            if not options.quiet:
                 print '#  ', line
             sys.stdout.write(options.colors.reset())
                 
             #print 'direction = "%s", packet = "%s"' % (direction, packet)
             
             if packet[0] == '+':
-                print 'ACK'
+                if not options.quiet: print 'ACK'
+                continue
             elif packet[0] == '-':
-                print 'NACK'
+                if not options.quiet: print 'NACK'
+                continue
             elif packet[0] == '$':
                 m = packet_contents_name_regex.match(packet)
                 if m:
@@ -921,7 +940,7 @@ def parse_gdb_log_file(file, options):
                             last_command_packet = contents
                             gdb_remote_commands[last_command]['cmd'](options, last_command, last_command_args)
                         else:
-                            packet_match = packet_name_regex.match (line[idx+14:])
+                            packet_match = packet_name_regex.match (contents)
                             if packet_match:
                                 packet_name = packet_match.group(1)
                                 for tricky_cmd in tricky_commands:
@@ -943,6 +962,9 @@ def parse_gdb_log_file(file, options):
         match = timestamp_regex.match (line)
         if match:
             curr_time = float (match.group(2))
+            if last_time and not is_command:
+                delta = curr_time - last_time
+                packet_times.append(delta)
             delta = 0.0
             if base_time:
                 delta = curr_time - last_time
@@ -965,6 +987,8 @@ def parse_gdb_log_file(file, options):
             last_time = curr_time
         # else:
         #     print line
+    (average, std_dev) = calculate_mean_and_standard_deviation(packet_times)
+    print '%u packets with average packet time of %f and standard deviation of %f' % (len(packet_times), average, std_dev)
     if packet_total_times:
         total_packet_time = 0.0
         total_packet_count = 0
@@ -978,7 +1002,7 @@ def parse_gdb_log_file(file, options):
 
         print '#---------------------------------------------------'
         print '# Packet timing summary:'
-        print '# Totals: time - %6f count %6d' % (total_packet_time, total_packet_count)
+        print '# Totals: time = %6f, count = %6d' % (total_packet_time, total_packet_count)
         print '#---------------------------------------------------'
         print '# Packet                   Time (sec) Percent Count '
         print '#------------------------- ---------- ------- ------'