You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.9 KiB
136 lines
4.9 KiB
#!/usr/bin/env 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 optparse
|
|
import os
|
|
import shlex
|
|
import re
|
|
import tempfile
|
|
|
|
|
|
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 log_file
|
|
if log_file:
|
|
result.PutCString(
|
|
'error: logging is already in progress with file "%s"',
|
|
log_file)
|
|
else:
|
|
args_len = len(args)
|
|
if args_len == 0:
|
|
log_file = tempfile.mktemp()
|
|
elif len(args) == 1:
|
|
log_file = args[0]
|
|
|
|
if log_file:
|
|
debugger.HandleCommand(
|
|
'log enable --threadsafe --timestamp --file "%s" gdb-remote packets' %
|
|
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." %
|
|
log_file)
|
|
return
|
|
|
|
result.PutCString('error: invalid log file path')
|
|
result.PutCString(usage)
|
|
|
|
|
|
def parse_time_log(debugger, command, result, dict):
|
|
# Any commands whose names might be followed by more valid C identifier
|
|
# characters must be listed here
|
|
command_args = shlex.split(command)
|
|
parse_time_log_args(command_args)
|
|
|
|
|
|
def parse_time_log_args(command_args):
|
|
usage = "usage: parse_time_log [options] [<LOGFILEPATH>]"
|
|
description = '''Parse a log file that contains timestamps and convert the timestamps to delta times between log lines.'''
|
|
parser = optparse.OptionParser(
|
|
description=description,
|
|
prog='parse_time_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
|
|
for log_file in args:
|
|
parse_log_file(log_file, options)
|
|
|
|
|
|
def parse_log_file(file, options):
|
|
'''Parse a log file that was contains timestamps. These logs are typically
|
|
generated using:
|
|
(lldb) log enable --threadsafe --timestamp --file <FILE> ....
|
|
|
|
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.'''
|
|
|
|
print('#----------------------------------------------------------------------')
|
|
print("# Log file: '%s'" % file)
|
|
print('#----------------------------------------------------------------------')
|
|
|
|
timestamp_regex = re.compile('(\s*)([1-9][0-9]+\.[0-9]+)([^0-9].*)$')
|
|
|
|
base_time = 0.0
|
|
last_time = 0.0
|
|
file = open(file)
|
|
lines = file.read().splitlines()
|
|
for line in lines:
|
|
match = timestamp_regex.match(line)
|
|
if match:
|
|
curr_time = float(match.group(2))
|
|
delta = 0.0
|
|
if base_time:
|
|
delta = curr_time - last_time
|
|
else:
|
|
base_time = curr_time
|
|
|
|
print('%s%.6f %+.6f%s' % (match.group(1), curr_time - base_time, delta, match.group(3)))
|
|
last_time = curr_time
|
|
else:
|
|
print(line)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
parse_time_log_args(sys.argv[1:])
|
|
|
|
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 delta.parse_time_log parse_time_log')
|
|
print('The "parse_time_log" command is now installed and ready for use, type "parse_time_log --help" for more information')
|