ia64/xen-unstable

view tools/xentrace/xentrace_format @ 7909:378e1c58bcd2

The xentrace_format script doesn't work on x86/64. Python pads the input
structure because the first field is 32 bits and the next is 64 bits,
whereas x86-32 doesn't pad. The quick fix is to read the cpu id
separately as a 32bit value, then read the rest of the trace record.
Here is a little patch that does that. Tested on x86/32 SMP and x86/64.


Signed-off-by: Rob Gardner <rob.gardner@hp.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Nov 18 17:54:23 2005 +0100 (2005-11-18)
parents 0c8a248ff045
children 167790b102ac
line source
1 #!/usr/bin/env python
3 # by Mark Williamson, (C) 2004 Intel Research Cambridge
5 # Program for reformatting trace buffer output according to user-supplied rules
7 import re, sys, string, signal, struct, os, getopt
9 def usage():
10 print >> sys.stderr, \
11 "Usage: " + sys.argv[0] + """ defs-file
12 Parses trace data in binary format, as output by Xentrace and
13 reformats it according to the rules in a file of definitions. The
14 rules in this file should have the format ({ and } show grouping
15 and are not part of the syntax):
17 {event_id}{whitespace}{text format string}
19 The textual format string may include format specifiers, such as:
20 %(cpu)d, %(tsc)d, %(event)d, %(1)d, %(2)d, %(3)d, %(4)d, %(5)d
21 [ the 'd' format specifier outputs in decimal, alternatively 'x'
22 will output in hexadecimal and 'o' will output in octal ]
24 Which correspond to the CPU number, event ID, timestamp counter and
25 the 5 data fields from the trace record. There should be one such
26 rule for each type of event.
28 Depending on your system and the volume of trace buffer data,
29 this script may not be able to keep up with the output of xentrace
30 if it is piped directly. In these circumstances you should have
31 xentrace output to a file for processing off-line.
32 """
33 sys.exit(1)
35 def read_defs(defs_file):
36 defs = {}
38 fd = open(defs_file)
40 reg = re.compile('(\S+)\s+(\S.*)')
42 while True:
43 line = fd.readline()
44 if not line:
45 break
47 if line[0] == '#' or line[0] == '\n':
48 continue
50 m = reg.match(line)
52 if not m: print >> sys.stderr, "Bad format file" ; sys.exit(1)
54 defs[str(eval(m.group(1)))] = m.group(2)
56 return defs
58 def sighand(x,y):
59 global interrupted
60 interrupted = 1
62 ##### Main code
64 mhz = 0
66 if len(sys.argv) < 2:
67 usage()
69 try:
70 opts, arg = getopt.getopt(sys.argv[1:], "c:" )
72 for opt in opts:
73 if opt[0] == '-c' : mhz = int(opt[1])
75 except getopt.GetoptError:
76 usage()
78 signal.signal(signal.SIGTERM, sighand)
79 signal.signal(signal.SIGHUP, sighand)
80 signal.signal(signal.SIGINT, sighand)
82 interrupted = 0
84 defs = read_defs(arg[0])
86 # structure of trace record + prepended CPU id (as output by xentrace):
87 # CPU(I) TSC(Q) EVENT(L) D1(L) D2(L) D3(L) D4(L) D5(L)
88 # read CPU id separately to avoid structure packing problems on 64-bit arch.
89 CPUREC = "I"
90 TRCREC = "QLLLLLL"
92 last_tsc = [0,0,0,0,0,0,0,0]
94 i=0
96 while not interrupted:
97 try:
98 i=i+1
99 line = sys.stdin.read(struct.calcsize(CPUREC))
100 if not line:
101 break
102 cpu = struct.unpack(CPUREC, line)[0]
104 line = sys.stdin.read(struct.calcsize(TRCREC))
105 if not line:
106 break
108 (tsc, event, d1, d2, d3, d4, d5) = struct.unpack(TRCREC, line)
110 #tsc = (tscH<<32) | tscL
112 #print i, tsc
114 if tsc < last_tsc[cpu]:
115 print "TSC stepped backward cpu %d ! %d %d" % (cpu,tsc,last_tsc[cpu])
117 last_tsc[cpu] = tsc
119 if mhz:
120 tsc = tsc / (mhz*1000000.0)
122 args = {'cpu' : cpu,
123 'tsc' : tsc,
124 'event' : event,
125 '1' : d1,
126 '2' : d2,
127 '3' : d3,
128 '4' : d4,
129 '5' : d5 }
131 try:
133 if defs.has_key(str(event)):
134 print defs[str(event)] % args
135 else:
136 if defs.has_key(str(0)): print defs[str(0)] % args
137 except TypeError:
138 print defs[str(event)]
139 print args
142 except IOError, struct.error: sys.exit()