debuggers.hg

annotate tools/misc/xensymoops @ 22848:6341fe0f4e5a

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