#!/usr/bin/python

#----------------------------------------------------------------------
# This module will enable GDB remote packet logging when the
# 'start_gdb_log' command is called with a filename to log to. When the
# 'stop_gdb_log' command is called, it will disable the logging and
# print out statistics about how long commands took to execute and also
# will primnt ou
# Be sure to add the python path that points to the LLDB shared library.
#
# To use this in the embedded python interpreter using "lldb" just
# import it with the full path using the "command script import"
# command. This can be done from the LLDB command line:
#   (lldb) command script import /path/to/gdbremote.py
# Or it can be added to your ~/.lldbinit file so this module is always
# available.
#----------------------------------------------------------------------

from __future__ import print_function
import binascii
import subprocess
import json
import math
import optparse
import os
import re
import shlex
import string
import sys
import tempfile
import xml.etree.ElementTree as ET

#----------------------------------------------------------------------
# Global variables
#----------------------------------------------------------------------
g_log_file = ''
g_byte_order = 'little'
g_number_regex = re.compile('^(0x[0-9a-fA-F]+|[0-9]+)')
g_thread_id_regex = re.compile('^(-1|[0-9a-fA-F]+|0)')


class TerminalColors:
    '''Simple terminal colors class'''

    def __init__(self, enabled=True):
        # TODO: discover terminal type from "file" and disable if
        # it can't handle the color codes
        self.enabled = enabled

    def reset(self):
        '''Reset all terminal colors and formatting.'''
        if self.enabled:
            return "\x1b[0m"
        return ''

    def bold(self, on=True):
        '''Enable or disable bold depending on the "on" parameter.'''
        if self.enabled:
            if on:
                return "\x1b[1m"
            else:
                return "\x1b[22m"
        return ''

    def italics(self, on=True):
        '''Enable or disable italics depending on the "on" parameter.'''
        if self.enabled:
            if on:
                return "\x1b[3m"
            else:
                return "\x1b[23m"
        return ''

    def underline(self, on=True):
        '''Enable or disable underline depending on the "on" parameter.'''
        if self.enabled:
            if on:
                return "\x1b[4m"
            else:
                return "\x1b[24m"
        return ''

    def inverse(self, on=True):
        '''Enable or disable inverse depending on the "on" parameter.'''
        if self.enabled:
            if on:
                return "\x1b[7m"
            else:
                return "\x1b[27m"
        return ''

    def strike(self, on=True):
        '''Enable or disable strike through depending on the "on" parameter.'''
        if self.enabled:
            if on:
                return "\x1b[9m"
            else:
                return "\x1b[29m"
        return ''

    def black(self, fg=True):
        '''Set the foreground or background color to black.
        The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
        if self.enabled:
            if fg:
                return "\x1b[30m"
            else:
                return "\x1b[40m"
        return ''

    def red(self, fg=True):
        '''Set the foreground or background color to red.
        The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
        if self.enabled:
            if fg:
                return "\x1b[31m"
            else:
                return "\x1b[41m"
        return ''

    def green(self, fg=True):
        '''Set the foreground or background color to green.
        The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
        if self.enabled:
            if fg:
                return "\x1b[32m"
            else:
                return "\x1b[42m"
        return ''

    def yellow(self, fg=True):
        '''Set the foreground or background color to yellow.
        The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
        if self.enabled:
            if fg:
                return "\x1b[33m"
            else:
                return "\x1b[43m"
        return ''

    def blue(self, fg=True):
        '''Set the foreground or background color to blue.
        The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
        if self.enabled:
            if fg:
                return "\x1b[34m"
            else:
                return "\x1b[44m"
        return ''

    def magenta(self, fg=True):
        '''Set the foreground or background color to magenta.
        The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
        if self.enabled:
            if fg:
                return "\x1b[35m"
            else:
                return "\x1b[45m"
        return ''

    def cyan(self, fg=True):
        '''Set the foreground or background color to cyan.
        The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
        if self.enabled:
            if fg:
                return "\x1b[36m"
            else:
                return "\x1b[46m"
        return ''

    def white(self, fg=True):
        '''Set the foreground or background color to white.
        The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
        if self.enabled:
            if fg:
                return "\x1b[37m"
            else:
                return "\x1b[47m"
        return ''

    def default(self, fg=True):
        '''Set the foreground or background color to the default.
        The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
        if self.enabled:
            if fg:
                return "\x1b[39m"
            else:
                return "\x1b[49m"
        return ''


def start_gdb_log(debugger, command, result, dict):
    '''Start logging GDB remote packets by enabling logging with timestamps and
    thread safe logging. Follow a call to this function with a call to "stop_gdb_log"
    in order to dump out the commands.'''
    global g_log_file
    command_args = shlex.split(command)
    usage = "usage: start_gdb_log [options] [<LOGFILEPATH>]"
    description = '''The command enables GDB remote packet logging with timestamps. The packets will be logged to <LOGFILEPATH> if supplied, or a temporary file will be used. Logging stops when stop_gdb_log is called and the packet times will
    be aggregated and displayed.'''
    parser = optparse.OptionParser(
        description=description,
        prog='start_gdb_log',
        usage=usage)
    parser.add_option(
        '-v',
        '--verbose',
        action='store_true',
        dest='verbose',
        help='display verbose debug info',
        default=False)
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return

    if g_log_file:
        result.PutCString(
            'error: logging is already in progress with file "%s"' %
            g_log_file)
    else:
        args_len = len(args)
        if args_len == 0:
            g_log_file = tempfile.mktemp()
        elif len(args) == 1:
            g_log_file = args[0]

        if g_log_file:
            debugger.HandleCommand(
                'log enable --threadsafe --timestamp --file "%s" gdb-remote packets' %
                g_log_file)
            result.PutCString(
                "GDB packet logging enable with log file '%s'\nUse the 'stop_gdb_log' command to stop logging and show packet statistics." %
                g_log_file)
            return

        result.PutCString('error: invalid log file path')
    result.PutCString(usage)


def stop_gdb_log(debugger, command, result, dict):
    '''Stop logging GDB remote packets to the file that was specified in a call
    to "start_gdb_log" and normalize the timestamps to be relative to the first
    timestamp in the log file. Also print out statistics for how long each
    command took to allow performance bottlenecks to be determined.'''
    global g_log_file
    # Any commands whose names might be followed by more valid C identifier
    # characters must be listed here
    command_args = shlex.split(command)
    usage = "usage: stop_gdb_log [options]"
    description = '''The command stops a previously enabled GDB remote packet logging command. Packet logging must have been previously enabled with a call to start_gdb_log.'''
    parser = optparse.OptionParser(
        description=description,
        prog='stop_gdb_log',
        usage=usage)
    parser.add_option(
        '-v',
        '--verbose',
        action='store_true',
        dest='verbose',
        help='display verbose debug info',
        default=False)
    parser.add_option(
        '-q',
        '--quiet',
        action='store_true',
        dest='quiet',
        help='display verbose debug info',
        default=False)
    parser.add_option(
        '-C',
        '--color',
        action='store_true',
        dest='color',
        help='add terminal colors',
        default=False)
    parser.add_option(
        '-c',
        '--sort-by-count',
        action='store_true',
        dest='sort_count',
        help='display verbose debug info',
        default=False)
    parser.add_option(
        '-s',
        '--symbolicate',
        action='store_true',
        dest='symbolicate',
        help='symbolicate addresses in log using current "lldb.target"',
        default=False)
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return
    options.colors = TerminalColors(options.color)
    options.symbolicator = None
    if options.symbolicate:
        if lldb.target:
            import lldb.utils.symbolication
            options.symbolicator = lldb.utils.symbolication.Symbolicator()
            options.symbolicator.target = lldb.target
        else:
            print("error: can't symbolicate without a target")

    if not g_log_file:
        result.PutCString(
            'error: logging must have been previously enabled with a call to "stop_gdb_log"')
    elif os.path.exists(g_log_file):
        if len(args) == 0:
            debugger.HandleCommand('log disable gdb-remote packets')
            result.PutCString(
                "GDB packet logging disabled. Logged packets are in '%s'" %
                g_log_file)
            parse_gdb_log_file(g_log_file, options)
        else:
            result.PutCString(usage)
    else:
        print('error: the GDB packet log file "%s" does not exist' % g_log_file)


def is_hex_byte(str):
    if len(str) == 2:
        return str[0] in string.hexdigits and str[1] in string.hexdigits
    return False

def get_hex_string_if_all_printable(str):
    try:
        s = binascii.unhexlify(str).decode()
        if all(c in string.printable for c in s):
            return s
    except (TypeError, binascii.Error, UnicodeDecodeError):
        pass
    return None

# global register info list
g_register_infos = list()
g_max_register_info_name_len = 0


class RegisterInfo:
    """Class that represents register information"""

    def __init__(self, kvp):
        self.info = dict()
        for kv in kvp:
            key = kv[0]
            value = kv[1]
            self.info[key] = value

    def name(self):
        '''Get the name of the register.'''
        if self.info and 'name' in self.info:
            return self.info['name']
        return None

    def bit_size(self):
        '''Get the size in bits of the register.'''
        if self.info and 'bitsize' in self.info:
            return int(self.info['bitsize'])
        return 0

    def byte_size(self):
        '''Get the size in bytes of the register.'''
        return self.bit_size() / 8

    def get_value_from_hex_string(self, hex_str):
        '''Dump the register value given a native byte order encoded hex ASCII byte string.'''
        encoding = self.info['encoding']
        bit_size = self.bit_size()
        packet = Packet(hex_str)
        if encoding == 'uint':
            uval = packet.get_hex_uint(g_byte_order)
            if bit_size == 8:
                return '0x%2.2x' % (uval)
            elif bit_size == 16:
                return '0x%4.4x' % (uval)
            elif bit_size == 32:
                return '0x%8.8x' % (uval)
            elif bit_size == 64:
                return '0x%16.16x' % (uval)
        bytes = list()
        uval = packet.get_hex_uint8()
        while uval is not None:
            bytes.append(uval)
            uval = packet.get_hex_uint8()
        value_str = '0x'
        if g_byte_order == 'little':
            bytes.reverse()
        for byte in bytes:
            value_str += '%2.2x' % byte
        return '%s' % (value_str)

    def __str__(self):
        '''Dump the register info key/value pairs'''
        s = ''
        for key in self.info.keys():
            if s:
                s += ', '
            s += "%s=%s " % (key, self.info[key])
        return s


class Packet:
    """Class that represents a packet that contains string data"""

    def __init__(self, packet_str):
        self.str = packet_str

    def peek_char(self):
        ch = 0
        if self.str:
            ch = self.str[0]
        return ch

    def get_char(self):
        ch = 0
        if self.str:
            ch = self.str[0]
            self.str = self.str[1:]
        return ch

    def skip_exact_string(self, s):
        if self.str and self.str.startswith(s):
            self.str = self.str[len(s):]
            return True
        else:
            return False

    def get_thread_id(self, fail_value=-1):
        match = g_number_regex.match(self.str)
        if match:
            number_str = match.group(1)
            self.str = self.str[len(number_str):]
            return int(number_str, 0)
        else:
            return fail_value

    def get_hex_uint8(self):
        if self.str and len(self.str) >= 2 and self.str[
                0] in string.hexdigits and self.str[1] in string.hexdigits:
            uval = int(self.str[0:2], 16)
            self.str = self.str[2:]
            return uval
        return None

    def get_hex_uint16(self, byte_order):
        uval = 0
        if byte_order == 'big':
            uval |= self.get_hex_uint8() << 8
            uval |= self.get_hex_uint8()
        else:
            uval |= self.get_hex_uint8()
            uval |= self.get_hex_uint8() << 8
        return uval

    def get_hex_uint32(self, byte_order):
        uval = 0
        if byte_order == 'big':
            uval |= self.get_hex_uint8() << 24
            uval |= self.get_hex_uint8() << 16
            uval |= self.get_hex_uint8() << 8
            uval |= self.get_hex_uint8()
        else:
            uval |= self.get_hex_uint8()
            uval |= self.get_hex_uint8() << 8
            uval |= self.get_hex_uint8() << 16
            uval |= self.get_hex_uint8() << 24
        return uval

    def get_hex_uint64(self, byte_order):
        uval = 0
        if byte_order == 'big':
            uval |= self.get_hex_uint8() << 56
            uval |= self.get_hex_uint8() << 48
            uval |= self.get_hex_uint8() << 40
            uval |= self.get_hex_uint8() << 32
            uval |= self.get_hex_uint8() << 24
            uval |= self.get_hex_uint8() << 16
            uval |= self.get_hex_uint8() << 8
            uval |= self.get_hex_uint8()
        else:
            uval |= self.get_hex_uint8()
            uval |= self.get_hex_uint8() << 8
            uval |= self.get_hex_uint8() << 16
            uval |= self.get_hex_uint8() << 24
            uval |= self.get_hex_uint8() << 32
            uval |= self.get_hex_uint8() << 40
            uval |= self.get_hex_uint8() << 48
            uval |= self.get_hex_uint8() << 56
        return uval

    def get_number(self, fail_value=-1):
        '''Get a number from the packet. The number must be in big endian format and should be parsed
        according to its prefix (starts with "0x" means hex, starts with "0" means octal, starts with
        [1-9] means decimal, etc)'''
        match = g_number_regex.match(self.str)
        if match:
            number_str = match.group(1)
            self.str = self.str[len(number_str):]
            return int(number_str, 0)
        else:
            return fail_value

    def get_hex_ascii_str(self, n=0):
        hex_chars = self.get_hex_chars(n)
        if hex_chars:
            return binascii.unhexlify(hex_chars)
        else:
            return None

    def get_hex_chars(self, n=0):
        str_len = len(self.str)
        if n == 0:
            # n was zero, so we need to determine all hex chars and
            # stop when we hit the end of the string of a non-hex character
            while n < str_len and self.str[n] in string.hexdigits:
                n = n + 1
        else:
            if n > str_len:
                return None  # Not enough chars
            # Verify all chars are hex if a length was specified
            for i in range(n):
                if self.str[i] not in string.hexdigits:
                    return None  # Not all hex digits
        if n == 0:
            return None
        hex_str = self.str[0:n]
        self.str = self.str[n:]
        return hex_str

    def get_hex_uint(self, byte_order, n=0):
        if byte_order == 'big':
            hex_str = self.get_hex_chars(n)
            if hex_str is None:
                return None
            return int(hex_str, 16)
        else:
            uval = self.get_hex_uint8()
            if uval is None:
                return None
            uval_result = 0
            shift = 0
            while uval is not None:
                uval_result |= (uval << shift)
                shift += 8
                uval = self.get_hex_uint8()
            return uval_result

    def get_key_value_pairs(self):
        kvp = list()
        if ';' in self.str:
            key_value_pairs = self.str.split(';')
            for key_value_pair in key_value_pairs:
                if len(key_value_pair):
                    kvp.append(key_value_pair.split(':', 1))
        return kvp

    def split(self, ch):
        return string.split(self.str, ch)

    def split_hex(self, ch, byte_order):
        hex_values = list()
        strings = string.split(self.str, ch)
        for str in strings:
            hex_values.append(Packet(str).get_hex_uint(byte_order))
        return hex_values

    def __str__(self):
        return self.str

    def __len__(self):
        return len(self.str)

g_thread_suffix_regex = re.compile(';thread:([0-9a-fA-F]+);')


def get_thread_from_thread_suffix(str):
    if str:
        match = g_thread_suffix_regex.match(str)
        if match:
            return int(match.group(1), 16)
    return None


def cmd_qThreadStopInfo(options, cmd, args):
    packet = Packet(args)
    tid = packet.get_hex_uint('big')
    print("get_thread_stop_info  (tid = 0x%x)" % (tid))


def cmd_stop_reply(options, cmd, args):
    print("get_last_stop_info()")
    return False


def rsp_stop_reply(options, cmd, cmd_args, rsp):
    global g_byte_order
    packet = Packet(rsp)
    stop_type = packet.get_char()
    if stop_type == 'T' or stop_type == 'S':
        signo = packet.get_hex_uint8()
        key_value_pairs = packet.get_key_value_pairs()
        for key_value_pair in key_value_pairs:
            key = key_value_pair[0]
            if is_hex_byte(key):
                reg_num = Packet(key).get_hex_uint8()
                if reg_num < len(g_register_infos):
                    reg_info = g_register_infos[reg_num]
                    key_value_pair[0] = reg_info.name()
                    key_value_pair[1] = reg_info.get_value_from_hex_string(
                        key_value_pair[1])
            elif key == 'jthreads' or key == 'jstopinfo':
                key_value_pair[1] = binascii.unhexlify(key_value_pair[1])
        key_value_pairs.insert(0, ['signal', signo])
        print('stop_reply():')
        dump_key_value_pairs(key_value_pairs)
    elif stop_type == 'W':
        exit_status = packet.get_hex_uint8()
        print('stop_reply(): exit (status=%i)' % exit_status)
    elif stop_type == 'O':
        print('stop_reply(): stdout = "%s"' % packet.str)


def cmd_unknown_packet(options, cmd, args):
    if args:
        print("cmd: %s, args: %s", cmd, args)
    else:
        print("cmd: %s", cmd)
    return False


def cmd_qSymbol(options, cmd, args):
    if args == ':':
        print('ready to serve symbols')
    else:
        packet = Packet(args)
        symbol_addr = packet.get_hex_uint('big')
        if symbol_addr is None:
            if packet.skip_exact_string(':'):
                symbol_name = packet.get_hex_ascii_str()
                print('lookup_symbol("%s") -> symbol not available yet' % (symbol_name))
            else:
                print('error: bad command format')
        else:
            if packet.skip_exact_string(':'):
                symbol_name = packet.get_hex_ascii_str()
                print('lookup_symbol("%s") -> 0x%x' % (symbol_name, symbol_addr))
            else:
                print('error: bad command format')

def cmd_QSetWithHexString(options, cmd, args):
    print('%s("%s")' % (cmd[:-1], binascii.unhexlify(args)))

def cmd_QSetWithString(options, cmd, args):
    print('%s("%s")' % (cmd[:-1], args))

def cmd_QSetWithUnsigned(options, cmd, args):
    print('%s(%i)' % (cmd[:-1], int(args)))

def rsp_qSymbol(options, cmd, cmd_args, rsp):
    if len(rsp) == 0:
        print("Unsupported")
    else:
        if rsp == "OK":
            print("No more symbols to lookup")
        else:
            packet = Packet(rsp)
            if packet.skip_exact_string("qSymbol:"):
                symbol_name = packet.get_hex_ascii_str()
                print('lookup_symbol("%s")' % (symbol_name))
            else:
                print('error: response string should start with "qSymbol:": respnse is "%s"' % (rsp))


def cmd_qXfer(options, cmd, args):
    # $qXfer:features:read:target.xml:0,1ffff#14
    print("read target special data %s" % (args))
    return True


def rsp_qXfer(options, cmd, cmd_args, rsp):
    data = cmd_args.split(':')
    if data[0] == 'features':
        if data[1] == 'read':
            filename, extension = os.path.splitext(data[2])
            if extension == '.xml':
                response = Packet(rsp)
                xml_string = response.get_hex_ascii_str()
                if xml_string:
                    ch = xml_string[0]
                    if ch == 'l':
                        xml_string = xml_string[1:]
                        xml_root = ET.fromstring(xml_string)
                        for reg_element in xml_root.findall("./feature/reg"):
                            if not 'value_regnums' in reg_element.attrib:
                                reg_info = RegisterInfo([])
                                if 'name' in reg_element.attrib:
                                    reg_info.info[
                                        'name'] = reg_element.attrib['name']
                                else:
                                    reg_info.info['name'] = 'unspecified'
                                if 'encoding' in reg_element.attrib:
                                    reg_info.info['encoding'] = reg_element.attrib[
                                        'encoding']
                                else:
                                    reg_info.info['encoding'] = 'uint'
                                if 'offset' in reg_element.attrib:
                                    reg_info.info[
                                        'offset'] = reg_element.attrib['offset']
                                if 'bitsize' in reg_element.attrib:
                                    reg_info.info[
                                        'bitsize'] = reg_element.attrib['bitsize']
                                g_register_infos.append(reg_info)
                        print('XML for "%s":' % (data[2]))
                        ET.dump(xml_root)


def cmd_A(options, cmd, args):
    print('launch process:')
    packet = Packet(args)
    while True:
        arg_len = packet.get_number()
        if arg_len == -1:
            break
        if not packet.skip_exact_string(','):
            break
        arg_idx = packet.get_number()
        if arg_idx == -1:
            break
        if not packet.skip_exact_string(','):
            break
        arg_value = packet.get_hex_ascii_str(arg_len)
        print('argv[%u] = "%s"' % (arg_idx, arg_value))


def cmd_qC(options, cmd, args):
    print("query_current_thread_id()")


def rsp_qC(options, cmd, cmd_args, rsp):
    packet = Packet(rsp)
    if packet.skip_exact_string("QC"):
        tid = packet.get_thread_id()
        print("current_thread_id = %#x" % (tid))
    else:
        print("current_thread_id = old thread ID")


def cmd_query_packet(options, cmd, args):
    if args:
        print("%s%s" % (cmd, args))
    else:
        print("%s" % (cmd))
    return False


def rsp_ok_error(rsp):
    print("rsp: ", rsp)


def rsp_ok_means_supported(options, cmd, cmd_args, rsp):
    if rsp == 'OK':
        print("%s%s is supported" % (cmd, cmd_args))
    elif rsp == '':
        print("%s%s is not supported" % (cmd, cmd_args))
    else:
        print("%s%s -> %s" % (cmd, cmd_args, rsp))


def rsp_ok_means_success(options, cmd, cmd_args, rsp):
    if rsp == 'OK':
        print("success")
    elif rsp == '':
        print("%s%s is not supported" % (cmd, cmd_args))
    else:
        print("%s%s -> %s" % (cmd, cmd_args, rsp))


def dump_key_value_pairs(key_value_pairs):
    max_key_len = 0
    for key_value_pair in key_value_pairs:
        key_len = len(key_value_pair[0])
        if max_key_len < key_len:
            max_key_len = key_len
    for key_value_pair in key_value_pairs:
        key = key_value_pair[0]
        value = key_value_pair[1]
        unhex_value = get_hex_string_if_all_printable(value)
        if unhex_value:
            print("%*s = %s (%s)" % (max_key_len, key, value, unhex_value))
        else:
            print("%*s = %s" % (max_key_len, key, value))


def rsp_dump_key_value_pairs(options, cmd, cmd_args, rsp):
    if rsp:
        print('%s response:' % (cmd))
        packet = Packet(rsp)
        key_value_pairs = packet.get_key_value_pairs()
        dump_key_value_pairs(key_value_pairs)
    else:
        print("not supported")


def cmd_c(options, cmd, args):
    print("continue()")
    return False


def cmd_s(options, cmd, args):
    print("step()")
    return False


def cmd_qSpeedTest(options, cmd, args):
    print(("qSpeedTest: cmd='%s', args='%s'" % (cmd, args)))


def rsp_qSpeedTest(options, cmd, cmd_args, rsp):
    print(("qSpeedTest: rsp='%s' cmd='%s', args='%s'" % (rsp, cmd, args)))


def cmd_vCont(options, cmd, args):
    if args == '?':
        print("%s: get supported extended continue modes" % (cmd))
    else:
        got_other_threads = 0
        s = ''
        for thread_action in args[1:].split(';'):
            (short_action, thread) = thread_action.split(':', 1)
            tid = int(thread, 16)
            if short_action == 'c':
                action = 'continue'
            elif short_action == 's':
                action = 'step'
            elif short_action[0] == 'C':
                action = 'continue with signal 0x%s' % (short_action[1:])
            elif short_action == 'S':
                action = 'step with signal 0x%s' % (short_action[1:])
            else:
                action = short_action
            if s:
                s += ', '
            if tid == -1:
                got_other_threads = 1
                s += 'other-threads:'
            else:
                s += 'thread 0x%4.4x: %s' % (tid, action)
        if got_other_threads:
            print("extended_continue (%s)" % (s))
        else:
            print("extended_continue (%s, other-threads: suspend)" % (s))
    return False


def rsp_vCont(options, cmd, cmd_args, rsp):
    if cmd_args == '?':
        # Skip the leading 'vCont;'
        rsp = rsp[6:]
        modes = rsp.split(';')
        s = "%s: supported extended continue modes include: " % (cmd)

        for i, mode in enumerate(modes):
            if i:
                s += ', '
            if mode == 'c':
                s += 'continue'
            elif mode == 'C':
                s += 'continue with signal'
            elif mode == 's':
                s += 'step'
            elif mode == 'S':
                s += 'step with signal'
            elif mode == 't':
                s += 'stop'
            # else:
            #     s += 'unrecognized vCont mode: ', str(mode)
        print(s)
    elif rsp:
        if rsp[0] == 'T' or rsp[0] == 'S' or rsp[0] == 'W' or rsp[0] == 'X':
            rsp_stop_reply(options, cmd, cmd_args, rsp)
            return
        if rsp[0] == 'O':
            print("stdout: %s" % (rsp))
            return
    else:
        print("not supported (cmd = '%s', args = '%s', rsp = '%s')" % (cmd, cmd_args, rsp))


def cmd_vAttach(options, cmd, args):
    (extra_command, args) = string.split(args, ';')
    if extra_command:
        print("%s%s(%s)" % (cmd, extra_command, args))
    else:
        print("attach(pid = %u)" % int(args, 16))
    return False


def cmd_qRegisterInfo(options, cmd, args):
    print('query_register_info(reg_num=%i)' % (int(args, 16)))
    return False


def rsp_qRegisterInfo(options, cmd, cmd_args, rsp):
    global g_max_register_info_name_len
    print('query_register_info(reg_num=%i):' % (int(cmd_args, 16)), end=' ')
    if len(rsp) == 3 and rsp[0] == 'E':
        g_max_register_info_name_len = 0
        for reg_info in g_register_infos:
            name_len = len(reg_info.name())
            if g_max_register_info_name_len < name_len:
                g_max_register_info_name_len = name_len
        print(' DONE')
    else:
        packet = Packet(rsp)
        reg_info = RegisterInfo(packet.get_key_value_pairs())
        g_register_infos.append(reg_info)
        print(reg_info)
    return False


def cmd_qThreadInfo(options, cmd, args):
    if cmd == 'qfThreadInfo':
        query_type = 'first'
    else:
        query_type = 'subsequent'
    print('get_current_thread_list(type=%s)' % (query_type))
    return False


def rsp_qThreadInfo(options, cmd, cmd_args, rsp):
    packet = Packet(rsp)
    response_type = packet.get_char()
    if response_type == 'm':
        tids = packet.split_hex(';', 'big')
        for i, tid in enumerate(tids):
            if i:
                print(',', end=' ')
            print('0x%x' % (tid), end=' ')
        print()
    elif response_type == 'l':
        print('END')


def rsp_hex_big_endian(options, cmd, cmd_args, rsp):
    if rsp == '':
        print("%s%s is not supported" % (cmd, cmd_args))
    else:
        packet = Packet(rsp)
        uval = packet.get_hex_uint('big')
        print('%s: 0x%x' % (cmd, uval))


def cmd_read_mem_bin(options, cmd, args):
    # x0x7fff5fc39200,0x200
    packet = Packet(args)
    addr = packet.get_hex_uint('big')
    comma = packet.get_char()
    size = packet.get_hex_uint('big')
    print('binary_read_memory (addr = 0x%16.16x, size = %u)' % (addr, size))
    return False


def rsp_mem_bin_bytes(options, cmd, cmd_args, rsp):
    packet = Packet(cmd_args)
    addr = packet.get_hex_uint('big')
    comma = packet.get_char()
    size = packet.get_hex_uint('big')
    print('memory:')
    if size > 0:
        dump_hex_memory_buffer(addr, rsp)


def cmd_read_memory(options, cmd, args):
    packet = Packet(args)
    addr = packet.get_hex_uint('big')
    comma = packet.get_char()
    size = packet.get_hex_uint('big')
    print('read_memory (addr = 0x%16.16x, size = %u)' % (addr, size))
    return False


def dump_hex_memory_buffer(addr, hex_byte_str):
    packet = Packet(hex_byte_str)
    idx = 0
    ascii = ''
    uval = packet.get_hex_uint8()
    while uval is not None:
        if ((idx % 16) == 0):
            if ascii:
                print('  ', ascii)
                ascii = ''
            print('0x%x:' % (addr + idx), end=' ')
        print('%2.2x' % (uval), end=' ')
        if 0x20 <= uval and uval < 0x7f:
            ascii += '%c' % uval
        else:
            ascii += '.'
        uval = packet.get_hex_uint8()
        idx = idx + 1
    if ascii:
        print('  ', ascii)
        ascii = ''


def cmd_write_memory(options, cmd, args):
    packet = Packet(args)
    addr = packet.get_hex_uint('big')
    if packet.get_char() != ',':
        print('error: invalid write memory command (missing comma after address)')
        return
    size = packet.get_hex_uint('big')
    if packet.get_char() != ':':
        print('error: invalid write memory command (missing colon after size)')
        return
    print('write_memory (addr = 0x%16.16x, size = %u, data:' % (addr, size))
    dump_hex_memory_buffer(addr, packet.str)
    return False


def cmd_alloc_memory(options, cmd, args):
    packet = Packet(args)
    byte_size = packet.get_hex_uint('big')
    if packet.get_char() != ',':
        print('error: invalid allocate memory command (missing comma after address)')
        return
    print('allocate_memory (byte-size = %u (0x%x), permissions = %s)' % (byte_size, byte_size, packet.str))
    return False


def rsp_alloc_memory(options, cmd, cmd_args, rsp):
    packet = Packet(rsp)
    addr = packet.get_hex_uint('big')
    print('addr = 0x%x' % addr)


def cmd_dealloc_memory(options, cmd, args):
    packet = Packet(args)
    addr = packet.get_hex_uint('big')
    if packet.get_char() != ',':
        print('error: invalid allocate memory command (missing comma after address)')
    else:
        print('deallocate_memory (addr = 0x%x, permissions = %s)' % (addr, packet.str))
    return False


def rsp_memory_bytes(options, cmd, cmd_args, rsp):
    addr = Packet(cmd_args).get_hex_uint('big')
    dump_hex_memory_buffer(addr, rsp)


def get_register_name_equal_value(options, reg_num, hex_value_str):
    if reg_num < len(g_register_infos):
        reg_info = g_register_infos[reg_num]
        value_str = reg_info.get_value_from_hex_string(hex_value_str)
        s = reg_info.name() + ' = '
        if options.symbolicator:
            symbolicated_addresses = options.symbolicator.symbolicate(
                int(value_str, 0))
            if symbolicated_addresses:
                s += options.colors.magenta()
                s += '%s' % symbolicated_addresses[0]
                s += options.colors.reset()
                return s
        s += value_str
        return s
    else:
        reg_value = Packet(hex_value_str).get_hex_uint(g_byte_order)
        return 'reg(%u) = 0x%x' % (reg_num, reg_value)


def cmd_read_one_reg(options, cmd, args):
    packet = Packet(args)
    reg_num = packet.get_hex_uint('big')
    tid = get_thread_from_thread_suffix(packet.str)
    name = None
    if reg_num < len(g_register_infos):
        name = g_register_infos[reg_num].name()
    if packet.str:
        packet.get_char()  # skip ;
        thread_info = packet.get_key_value_pairs()
        tid = int(thread_info[0][1], 16)
    s = 'read_register (reg_num=%u' % reg_num
    if name:
        s += ' (%s)' % (name)
    if tid is not None:
        s += ', tid = 0x%4.4x' % (tid)
    s += ')'
    print(s)
    return False


def rsp_read_one_reg(options, cmd, cmd_args, rsp):
    packet = Packet(cmd_args)
    reg_num = packet.get_hex_uint('big')
    print(get_register_name_equal_value(options, reg_num, rsp))


def cmd_write_one_reg(options, cmd, args):
    packet = Packet(args)
    reg_num = packet.get_hex_uint('big')
    if packet.get_char() != '=':
        print('error: invalid register write packet')
    else:
        name = None
        hex_value_str = packet.get_hex_chars()
        tid = get_thread_from_thread_suffix(packet.str)
        s = 'write_register (reg_num=%u' % reg_num
        if name:
            s += ' (%s)' % (name)
        s += ', value = '
        s += get_register_name_equal_value(options, reg_num, hex_value_str)
        if tid is not None:
            s += ', tid = 0x%4.4x' % (tid)
        s += ')'
        print(s)
    return False


def dump_all_regs(packet):
    for reg_info in g_register_infos:
        nibble_size = reg_info.bit_size() / 4
        hex_value_str = packet.get_hex_chars(nibble_size)
        if hex_value_str is not None:
            value = reg_info.get_value_from_hex_string(hex_value_str)
            print('%*s = %s' % (g_max_register_info_name_len, reg_info.name(), value))
        else:
            return


def cmd_read_all_regs(cmd, cmd_args):
    packet = Packet(cmd_args)
    packet.get_char()  # toss the 'g' command character
    tid = get_thread_from_thread_suffix(packet.str)
    if tid is not None:
        print('read_all_register(thread = 0x%4.4x)' % tid)
    else:
        print('read_all_register()')
    return False


def rsp_read_all_regs(options, cmd, cmd_args, rsp):
    packet = Packet(rsp)
    dump_all_regs(packet)


def cmd_write_all_regs(options, cmd, args):
    packet = Packet(args)
    print('write_all_registers()')
    dump_all_regs(packet)
    return False

g_bp_types = ["software_bp", "hardware_bp", "write_wp", "read_wp", "access_wp"]


def cmd_bp(options, cmd, args):
    if cmd == 'Z':
        s = 'set_'
    else:
        s = 'clear_'
    packet = Packet(args)
    bp_type = packet.get_hex_uint('big')
    packet.get_char()  # Skip ,
    bp_addr = packet.get_hex_uint('big')
    packet.get_char()  # Skip ,
    bp_size = packet.get_hex_uint('big')
    s += g_bp_types[bp_type]
    s += " (addr = 0x%x, size = %u)" % (bp_addr, bp_size)
    print(s)
    return False


def cmd_mem_rgn_info(options, cmd, args):
    packet = Packet(args)
    packet.get_char()  # skip ':' character
    addr = packet.get_hex_uint('big')
    print('get_memory_region_info (addr=0x%x)' % (addr))
    return False


def cmd_kill(options, cmd, args):
    print('kill_process()')
    return False


def cmd_jThreadsInfo(options, cmd, args):
    print('jThreadsInfo()')
    return False


def cmd_jGetLoadedDynamicLibrariesInfos(options, cmd, args):
    print('jGetLoadedDynamicLibrariesInfos()')
    return False


def decode_packet(s, start_index=0):
    # print '\ndecode_packet("%s")' % (s[start_index:])
    index = s.find('}', start_index)
    have_escapes = index != -1
    if have_escapes:
        normal_s = s[start_index:index]
    else:
        normal_s = s[start_index:]
    # print 'normal_s = "%s"' % (normal_s)
    if have_escapes:
        escape_char = '%c' % (ord(s[index + 1]) ^ 0x20)
        # print 'escape_char for "%s" = %c' % (s[index:index+2], escape_char)
        return normal_s + escape_char + decode_packet(s, index + 2)
    else:
        return normal_s


def rsp_json(options, cmd, cmd_args, rsp):
    print('%s() reply:' % (cmd))
    json_tree = json.loads(rsp)
    print(json.dumps(json_tree, indent=4, separators=(',', ': ')))


def rsp_jGetLoadedDynamicLibrariesInfos(options, cmd, cmd_args, rsp):
    if cmd_args:
        rsp_json(options, cmd, cmd_args, rsp)
    else:
        rsp_ok_means_supported(options, cmd, cmd_args, rsp)

gdb_remote_commands = {
    '\\?': {'cmd': cmd_stop_reply, 'rsp': rsp_stop_reply, 'name': "stop reply pacpket"},
    'qThreadStopInfo': {'cmd': cmd_qThreadStopInfo, 'rsp': rsp_stop_reply, 'name': "stop reply pacpket"},
    '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_QSetWithUnsigned, 'rsp': rsp_ok_means_success, 'name': "set if we should detach on error"},
    'QSetDisableASLR:': {'cmd': cmd_QSetWithUnsigned, 'rsp': rsp_ok_means_success, 'name': "set if we should disable ASLR"},
    'qLaunchSuccess': {'cmd': cmd_query_packet, 'rsp': rsp_ok_means_success, 'name': "check on launch success for the A packet"},
    'A': {'cmd': cmd_A, 'rsp': rsp_ok_means_success, 'name': "launch process"},
    'QLaunchArch:': {'cmd': cmd_QSetWithString, 'rsp': rsp_ok_means_supported, 'name': "set the arch to launch in case the file contains multiple architectures"},
    'qVAttachOrWaitSupported': {'cmd': cmd_query_packet, 'rsp': rsp_ok_means_supported, 'name': "set the launch architecture"},
    'qHostInfo': {'cmd': cmd_query_packet, 'rsp': rsp_dump_key_value_pairs, 'name': "get host information"},
    'qC': {'cmd': cmd_qC, 'rsp': rsp_qC, 'name': "return the current thread ID"},
    'vCont': {'cmd': cmd_vCont, 'rsp': rsp_vCont, 'name': "extended continue command"},
    'qSpeedTest': {'cmd':cmd_qSpeedTest, 'rsp': rsp_qSpeedTest, 'name': 'speed test packdet'},
    'vAttach': {'cmd': cmd_vAttach, 'rsp': rsp_stop_reply, 'name': "attach to process"},
    'c': {'cmd': cmd_c, 'rsp': rsp_stop_reply, 'name': "continue"},
    's': {'cmd': cmd_s, 'rsp': rsp_stop_reply, 'name': "step"},
    'qRegisterInfo': {'cmd': cmd_qRegisterInfo, 'rsp': rsp_qRegisterInfo, 'name': "query register info"},
    'qfThreadInfo': {'cmd': cmd_qThreadInfo, 'rsp': rsp_qThreadInfo, 'name': "get current thread list"},
    '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"},
    'qXfer:': {'cmd': cmd_qXfer, 'rsp': rsp_qXfer, 'name': "qXfer"},
    'qSymbol:': {'cmd': cmd_qSymbol, 'rsp': rsp_qSymbol, 'name': "qSymbol"},
    'QSetSTDIN:' : {'cmd' : cmd_QSetWithHexString, 'rsp' : rsp_ok_means_success, 'name': "set STDIN prior to launching with A packet"},
    'QSetSTDOUT:' : {'cmd' : cmd_QSetWithHexString, 'rsp' : rsp_ok_means_success, 'name': "set STDOUT prior to launching with A packet"},
    'QSetSTDERR:' : {'cmd' : cmd_QSetWithHexString, 'rsp' : rsp_ok_means_success, 'name': "set STDERR prior to launching with A packet"},
    'QEnvironment:' : {'cmd' : cmd_QSetWithString, 'rsp' : rsp_ok_means_success, 'name': "set an environment variable prior to launching with A packet"},
    'QEnvironmentHexEncoded:' : {'cmd' : cmd_QSetWithHexString, 'rsp' : rsp_ok_means_success, 'name': "set an environment variable prior to launching with A packet"},
    'x': {'cmd': cmd_read_mem_bin, 'rsp': rsp_mem_bin_bytes, 'name': "read memory binary"},
    'X': {'cmd': cmd_write_memory, 'rsp': rsp_ok_means_success, 'name': "write memory binary"},
    '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"},
    '_m': {'cmd': cmd_dealloc_memory, 'rsp': rsp_ok_means_success, 'name': "deallocate memory"},
    'p': {'cmd': cmd_read_one_reg, 'rsp': rsp_read_one_reg, 'name': "read single register"},
    'P': {'cmd': cmd_write_one_reg, 'rsp': rsp_ok_means_success, 'name': "write single register"},
    'g': {'cmd': cmd_read_all_regs, 'rsp': rsp_read_all_regs, 'name': "read all registers"},
    'G': {'cmd': cmd_write_all_regs, 'rsp': rsp_ok_means_success, 'name': "write all registers"},
    'z': {'cmd': cmd_bp, 'rsp': rsp_ok_means_success, 'name': "clear breakpoint or watchpoint"},
    '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"},
    'jThreadsInfo': {'cmd': cmd_jThreadsInfo, 'rsp': rsp_json, 'name': "JSON get all threads info"},
    'jGetLoadedDynamicLibrariesInfos:': {'cmd': cmd_jGetLoadedDynamicLibrariesInfos, 'rsp': rsp_jGetLoadedDynamicLibrariesInfos, 'name': 'JSON get loaded dynamic libraries'},
}


def calculate_mean_and_standard_deviation(floats):
    sum = 0.0
    count = len(floats)
    if count == 0:
        return (0.0, 0.0)
    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(path, options):
    f = open(path)
    parse_gdb_log(f, options)
    f.close()


def round_up(n, incr):
    return float(((int(n) + incr) / incr) * incr)


def plot_latencies(sec_times):
    # import numpy as np
    import matplotlib.pyplot as plt

    for (i, name) in enumerate(sec_times.keys()):
        times = sec_times[name]
        if len(times) <= 1:
            continue
        plt.subplot(2, 1, 1)
        plt.title('Packet "%s" Times' % (name))
        plt.xlabel('Packet')
        units = 'ms'
        adj_times = []
        max_time = 0.0
        for time in times:
            time = time * 1000.0
            adj_times.append(time)
            if time > max_time:
                max_time = time
        if max_time < 1.0:
            units = 'us'
            max_time = 0.0
            for i in range(len(adj_times)):
                adj_times[i] *= 1000.0
                if adj_times[i] > max_time:
                    max_time = adj_times[i]
        plt.ylabel('Time (%s)' % (units))
        max_y = None
        for i in [5.0, 10.0, 25.0, 50.0]:
            if max_time < i:
                max_y = round_up(max_time, i)
                break
        if max_y is None:
            max_y = round_up(max_time, 100.0)
        plt.ylim(0.0, max_y)
        plt.plot(adj_times, 'o-')
        plt.show()


def parse_gdb_log(file, options):
    '''Parse a GDB log file that was generated by enabling logging with:
    (lldb) log enable --threadsafe --timestamp --file <FILE> gdb-remote packets
    This log file will contain timestamps and this function will then normalize
    those packets to be relative to the first value timestamp that is found and
    show delta times between log lines and also keep track of how long it takes
    for GDB remote commands to make a send/receive round trip. This can be
    handy when trying to figure out why some operation in the debugger is taking
    a long time during a preset set of debugger commands.'''

    tricky_commands = ['qRegisterInfo']
    timestamp_regex = re.compile('(\s*)([1-9][0-9]+\.[0-9]+)([^0-9].*)$')
    packet_name_regex = re.compile('([A-Za-z_]+)[^a-z]')
    packet_transmit_name_regex = re.compile(
        '(?P<direction>send|read) packet: (?P<packet>.*)')
    packet_contents_name_regex = re.compile('\$([^#]*)#[0-9a-fA-F]{2}')
    packet_checksum_regex = re.compile('.*#[0-9a-fA-F]{2}$')
    packet_names_regex_str = '(' + \
        '|'.join(gdb_remote_commands.keys()) + ')(.*)'
    packet_names_regex = re.compile(packet_names_regex_str)

    base_time = 0.0
    last_time = 0.0
    min_time = 100000000.0
    packet_total_times = {}
    all_packet_times = []
    packet_times = {}
    packet_counts = {}
    lines = file.read().splitlines()
    last_command = None
    last_command_args = None
    last_command_packet = None
    hide_next_response = False
    num_lines = len(lines)
    skip_count = 0
    for (line_index, line) in enumerate(lines):
        # See if we need to skip any lines
        if skip_count > 0:
            skip_count -= 1
            continue
        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 not options.quiet and not hide_next_response:
                print('#  ', line)
            sys.stdout.write(options.colors.reset())

            # print 'direction = "%s", packet = "%s"' % (direction, packet)

            if packet[0] == '+':
                if is_command:
                    print('-->', end=' ')
                else:
                    print('<--', end=' ')
                if not options.quiet:
                    print('ACK')
                continue
            elif packet[0] == '-':
                if is_command:
                    print('-->', end=' ')
                else:
                    print('<--', end=' ')
                if not options.quiet:
                    print('NACK')
                continue
            elif packet[0] == '$':
                m = packet_contents_name_regex.match(packet)
                if not m and packet[0] == '$':
                    multiline_packet = packet
                    idx = line_index + 1
                    while idx < num_lines:
                        if not options.quiet and not hide_next_response:
                            print('#  ', lines[idx])
                        multiline_packet += lines[idx]
                        m = packet_contents_name_regex.match(multiline_packet)
                        if m:
                            packet = multiline_packet
                            skip_count = idx - line_index
                            break
                        else:
                            idx += 1
                if m:
                    if is_command:
                        print('-->', end=' ')
                    else:
                        print('<--', end=' ')
                    contents = decode_packet(m.group(1))
                    if is_command:
                        hide_next_response = False
                        m = packet_names_regex.match(contents)
                        if m:
                            last_command = m.group(1)
                            if last_command == '?':
                                last_command = '\\?'
                            packet_name = last_command
                            last_command_args = m.group(2)
                            last_command_packet = contents
                            hide_next_response = gdb_remote_commands[last_command][
                                'cmd'](options, last_command, last_command_args)
                        else:
                            packet_match = packet_name_regex.match(contents)
                            if packet_match:
                                packet_name = packet_match.group(1)
                                for tricky_cmd in tricky_commands:
                                    if packet_name.find(tricky_cmd) == 0:
                                        packet_name = tricky_cmd
                            else:
                                packet_name = contents
                            last_command = None
                            last_command_args = None
                            last_command_packet = None
                    elif last_command:
                        gdb_remote_commands[last_command]['rsp'](
                            options, last_command, last_command_args, contents)
                else:
                    print('error: invalid packet: "', packet, '"')
            else:
                print('???')
        else:
            print('## ', line)
        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
                all_packet_times.append(delta)
            delta = 0.0
            if base_time:
                delta = curr_time - last_time
            else:
                base_time = curr_time

            if not is_command:
                if line.find('read packet: $') >= 0 and packet_name:
                    if packet_name in packet_total_times:
                        packet_total_times[packet_name] += delta
                        packet_counts[packet_name] += 1
                    else:
                        packet_total_times[packet_name] = delta
                        packet_counts[packet_name] = 1
                    if packet_name not in packet_times:
                        packet_times[packet_name] = []
                    packet_times[packet_name].append(delta)
                    packet_name = None
                if min_time > delta:
                    min_time = delta

            if not options or not options.quiet:
                print('%s%.6f %+.6f%s' % (match.group(1),
                                          curr_time - base_time,
                                          delta,
                                          match.group(3)))
            last_time = curr_time
        # else:
        #     print line
    (average, std_dev) = calculate_mean_and_standard_deviation(all_packet_times)
    if average and std_dev:
        print('%u packets with average packet time of %f and standard deviation of %f' % (len(all_packet_times), average, std_dev))
    if packet_total_times:
        total_packet_time = 0.0
        total_packet_count = 0
        for key, vvv in packet_total_times.items():
            # print '  key = (%s) "%s"' % (type(key), key)
            # print 'value = (%s) %s' % (type(vvv), vvv)
            # if type(vvv) == 'float':
            total_packet_time += vvv
        for key, vvv in packet_counts.items():
            total_packet_count += vvv

        print('#------------------------------------------------------------')
        print('# Packet timing summary:')
        print('# Totals: time = %6f, count = %6d' % (total_packet_time,
                                                     total_packet_count))
        print('# Min packet time: time = %6f' % (min_time))
        print('#------------------------------------------------------------')
        print('# Packet                   Time (sec)  Percent Count  Latency')
        print('#------------------------- ----------- ------- ------ -------')
        if options and options.sort_count:
            res = sorted(
                packet_counts,
                key=packet_counts.__getitem__,
                reverse=True)
        else:
            res = sorted(
                packet_total_times,
                key=packet_total_times.__getitem__,
                reverse=True)

        if last_time > 0.0:
            for item in res:
                packet_total_time = packet_total_times[item]
                packet_percent = (
                    packet_total_time / total_packet_time) * 100.0
                packet_count = packet_counts[item]
                print("  %24s %11.6f  %5.2f%% %6d %9.6f" % (
                        item, packet_total_time, packet_percent, packet_count,
                        float(packet_total_time) / float(packet_count)))
        if options.plot:
            plot_latencies(packet_times)

if __name__ == '__main__':
    usage = "usage: gdbremote [options]"
    description = '''The command disassembles a GDB remote packet log.'''
    parser = optparse.OptionParser(
        description=description,
        prog='gdbremote',
        usage=usage)
    parser.add_option(
        '-v',
        '--verbose',
        action='store_true',
        dest='verbose',
        help='display verbose debug info',
        default=False)
    parser.add_option(
        '--plot',
        action='store_true',
        dest='plot',
        help='plot packet latencies by packet type',
        default=False)
    parser.add_option(
        '-q',
        '--quiet',
        action='store_true',
        dest='quiet',
        help='display verbose debug info',
        default=False)
    parser.add_option(
        '-C',
        '--color',
        action='store_true',
        dest='color',
        help='add terminal colors',
        default=False)
    parser.add_option(
        '-c',
        '--sort-by-count',
        action='store_true',
        dest='sort_count',
        help='display verbose debug info',
        default=False)
    parser.add_option(
        '--crashlog',
        type='string',
        dest='crashlog',
        help='symbolicate using a darwin crash log file',
        default=False)
    try:
        (options, args) = parser.parse_args(sys.argv[1:])
    except:
        print('error: argument error')
        sys.exit(1)

    options.colors = TerminalColors(options.color)
    options.symbolicator = None
    if options.crashlog:
        import lldb
        lldb.debugger = lldb.SBDebugger.Create()
        import lldb.macosx.crashlog
        options.symbolicator = lldb.macosx.crashlog.CrashLog(options.crashlog)
        print('%s' % (options.symbolicator))

    # This script is being run from the command line, create a debugger in case we are
    # going to use any debugger functions in our function.
    if len(args):
        for file in args:
            print('#----------------------------------------------------------------------')
            print("# GDB remote log file: '%s'" % file)
            print('#----------------------------------------------------------------------')
            parse_gdb_log_file(file, options)
        if options.symbolicator:
            print('%s' % (options.symbolicator))
    else:
        parse_gdb_log(sys.stdin, options)

else:
    import lldb
    if lldb.debugger:
        # This initializer is being run from LLDB in the embedded command interpreter
        # Add any commands contained in this module to LLDB
        lldb.debugger.HandleCommand(
            'command script add -f gdbremote.start_gdb_log start_gdb_log')
        lldb.debugger.HandleCommand(
            'command script add -f gdbremote.stop_gdb_log stop_gdb_log')
        print('The "start_gdb_log" and "stop_gdb_log" commands are now installed and ready for use, type "start_gdb_log --help" or "stop_gdb_log --help" for more information')
