File:  [Qemu by Fabrice Bellard] / qemu / scripts / simpletrace.py
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:42:41 2018 UTC (3 years, 6 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0150, qemu0141, qemu0140, HEAD
qemu 0.14.0

    1: #!/usr/bin/env python
    2: #
    3: # Pretty-printer for simple trace backend binary trace files
    4: #
    5: # Copyright IBM, Corp. 2010
    6: #
    7: # This work is licensed under the terms of the GNU GPL, version 2.  See
    8: # the COPYING file in the top-level directory.
    9: #
   10: # For help see docs/tracing.txt
   11: 
   12: import sys
   13: import struct
   14: import re
   15: 
   16: header_event_id = 0xffffffffffffffff
   17: header_magic    = 0xf2b177cb0aa429b4
   18: header_version  = 0
   19: 
   20: trace_fmt = '=QQQQQQQQ'
   21: trace_len = struct.calcsize(trace_fmt)
   22: event_re  = re.compile(r'(disable\s+)?([a-zA-Z0-9_]+)\(([^)]*)\).*')
   23: 
   24: def err(msg):
   25:     sys.stderr.write(msg + '\n')
   26:     sys.exit(1)
   27: 
   28: def parse_events(fobj):
   29:     """Parse a trace-events file."""
   30: 
   31:     def get_argnames(args):
   32:         """Extract argument names from a parameter list."""
   33:         return tuple(arg.split()[-1].lstrip('*') for arg in args.split(','))
   34: 
   35:     events = {}
   36:     event_num = 0
   37:     for line in fobj:
   38:         m = event_re.match(line.strip())
   39:         if m is None:
   40:             continue
   41: 
   42:         disable, name, args = m.groups()
   43:         events[event_num] = (name,) + get_argnames(args)
   44:         event_num += 1
   45:     return events
   46: 
   47: def read_record(fobj):
   48:     """Deserialize a trace record from a file."""
   49:     s = fobj.read(trace_len)
   50:     if len(s) != trace_len:
   51:         return None
   52:     return struct.unpack(trace_fmt, s)
   53: 
   54: def read_trace_file(fobj):
   55:     """Deserialize trace records from a file."""
   56:     header = read_record(fobj)
   57:     if header is None or \
   58:        header[0] != header_event_id or \
   59:        header[1] != header_magic or \
   60:        header[2] != header_version:
   61:         err('not a trace file or incompatible version')
   62: 
   63:     while True:
   64:         rec = read_record(fobj)
   65:         if rec is None:
   66:             break
   67: 
   68:         yield rec
   69: 
   70: class Formatter(object):
   71:     def __init__(self, events):
   72:         self.events = events
   73:         self.last_timestamp = None
   74: 
   75:     def format_record(self, rec):
   76:         if self.last_timestamp is None:
   77:             self.last_timestamp = rec[1]
   78:         delta_ns = rec[1] - self.last_timestamp
   79:         self.last_timestamp = rec[1]
   80: 
   81:         event = self.events[rec[0]]
   82:         fields = [event[0], '%0.3f' % (delta_ns / 1000.0)]
   83:         for i in xrange(1, len(event)):
   84:             fields.append('%s=0x%x' % (event[i], rec[i + 1]))
   85:         return ' '.join(fields)
   86: 
   87: if len(sys.argv) != 3:
   88:     err('usage: %s <trace-events> <trace-file>' % sys.argv[0])
   89: 
   90: events = parse_events(open(sys.argv[1], 'r'))
   91: formatter = Formatter(events)
   92: for rec in read_trace_file(open(sys.argv[2], 'rb')):
   93:     print formatter.format_record(rec)

unix.superglobalmegacorp.com