Statistics
| Branch: | Revision:

root / simpletrace.py @ 11217a75

History | View | Annotate | Download (2.5 kB)

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