#!/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.
#----------------------------------------------------------------------

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)
        if all(c in string.printable for c in s):
            return s
    except TypeError:
        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 = 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):
        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 = string.split(cmd_args, ':')
    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 string.split(args[1:], ';'):
            (short_action, thread) = string.split(thread_action, ':')
            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 = string.split(rsp, ';')
        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')
