ia64/xen-unstable

view tools/misc/xensymoops @ 6422:e24fd7012ffb

merge?
author cl349@firebug.cl.cam.ac.uk
date Thu Aug 25 10:09:39 2005 +0000 (2005-08-25)
parents 0a4b76b6b5a0
children
line source
1 #!/usr/bin/env python
3 # An oops analyser for Xen
4 # Usage: xensymoops path-to-xen.s < oops-message
6 # There's probably some more features that could go in here but this
7 # is sufficient to analyse most errors in my code ;-)
9 # by Mark Williamson (C) 2004 Intel Research Cambridge
11 import re, sys
13 def read_oops():
14 """Process an oops message on stdin and return (eip_addr, stack_addrs)
16 eip_addr is the location of EIP at the point of the crash.
17 stack_addrs is a dictionary mapping potential code addresses in the stack
18 to their order in the stack trace.
19 """
20 stackaddr_ptn = "\[([a-z,0-9]*)\]"
21 stackaddr_re = re.compile(stackaddr_ptn)
23 eip_ptn = ".*EIP:.*<([a-z,0-9]*)>.*"
24 eip_re = re.compile(eip_ptn)
26 matches = 0
27 stack_addresses = {}
28 eip_addr = "Not known"
30 while True:
31 line = sys.stdin.readline()
32 if not line: break
34 m = eip_re.match(line)
35 if m: eip_addr = m.group(1)
37 m = stackaddr_re.findall(line)
39 for i in m:
40 stack_addresses[i] = matches
41 matches += 1
43 return (eip_addr, stack_addresses)
45 def usage():
46 print >> sys.stderr, """Usage: %s path-to-asm < oops-msg
47 The oops message should be fed to the standard input. The
48 command-line argument specifies the path to the Xen assembly dump
49 produced by \"make debug\". The location of EIP and the backtrace
50 will be output to standard output.
51 """ % sys.argv[0]
52 sys.exit()
54 ##### main
56 if len(sys.argv) != 2:
57 usage()
59 # get address of EIP and the potential code addresses from the stack
60 (eip_addr, stk_addrs) = read_oops()
62 # open Xen disassembly
63 asm_file = open(sys.argv[1])
65 # regexp to match addresses of code lines in the objdump
66 addr_ptn = "([a-z,0-9]*):"
67 addr_re = re.compile(addr_ptn)
69 # regexp to match the start of functions in the objdump
70 func_ptn = "(.*<[\S]*>):"
71 func_re = re.compile(func_ptn)
73 func = "<No function>" # holds the name of the current function being scanned
75 eip_func = "<No function>" # name of the function EIP was in
77 # list of (position in original backtrace, code address, function) tuples
78 # describing all the potential code addresses we identified in the backtrace
79 # whose addresses we also located in the objdump output
80 backtrace = []
82 while True:
83 line = asm_file.readline()
84 if not line: break
86 # if we've read the start of the function, record the name and address
87 fm = func_re.match(line)
88 if fm:
89 func = fm.group(1)
90 continue
92 # try match the address at the start of the line
93 m = addr_re.match(line)
94 if not m: continue
96 # we're on a code line...
98 address = m.group(1)
100 # if this address was seen as a potential code address in the backtrace then
101 # record it in the backtrace list
102 if stk_addrs.has_key(address):
103 backtrace.append((stk_addrs[address], address, func))
105 # if this was the address that EIP...
106 if address == eip_addr:
107 eip_func = func
110 print "EIP %s in function %s" % (eip_addr, eip_func)
111 print "Backtrace:"
113 # sorting will order primarily by the first element of each tuple,
114 # i.e. the order in the original oops
115 backtrace.sort()
117 for (i, a, f) in backtrace:
118 print "%s in function %s" % ( a, f )