forked from OpenRCE/paimei
-
Notifications
You must be signed in to change notification settings - Fork 5
/
crash_bin_explorer.py
110 lines (85 loc) · 3.15 KB
/
crash_bin_explorer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!c:\\python\\python.exe
"""
Crash Bin Explorer
Copyright (C) 2007 Pedram Amini <[email protected]>
$Id: crash_bin_explorer.py 231 2008-07-21 22:43:36Z pedram.amini $
Description:
Command line utility for exploring the results stored in serialized crash bin files. You can list all crashes
categorized in buckets, view the details of a specific crash, or generate a graph of all crashes and crash paths
based on stack-walk information.
The 'extra' field is what specifies the test case number. It's up to you to label your test cases in however manner
is appropriate to you.
"""
import getopt
import sys
import utils
import pgraph
USAGE = "\nUSAGE: crashbin_explorer.py <xxx.crashbin>" \
"\n [-t|--test id] dump the crash synopsis for a specific test case id" \
"\n [-g|--graph name] generate a graph of all crash paths, save to 'name'.udg\n"
#
# parse command line options.
#
try:
if len(sys.argv) < 2:
raise Exception
opts, args = getopt.getopt(sys.argv[2:], "t:g:", ["test=", "graph="])
except:
print USAGE
sys.exit(1)
test_id = graph_name = graph = None
for opt, arg in opts:
if opt in ("-t", "--test"): test_id = arg
if opt in ("-g", "--graph"): graph_name = arg
try:
crashbin = utils.crash_binning.crash_binning()
crashbin.import_file(sys.argv[1])
except:
print "unable to open crashbin: '%s'." % sys.argv[1]
sys.exit(1)
#
# display the full crash dump of a specific test case
#
if test_id:
for bin, crashes in crashbin.bins.iteritems():
for crash in crashes:
if test_id == crash.extra:
print crashbin.crash_synopsis(crash)
sys.exit(0)
#
# display an overview of all recorded crashes.
#
if graph_name:
graph = pgraph.graph()
for bin, crashes in crashbin.bins.iteritems():
synopsis = crashbin.crash_synopsis(crashes[0]).split("\n")[0]
if graph:
crash_node = pgraph.node(crashes[0].exception_address)
crash_node.count = len(crashes)
crash_node.label = "[%d] %s.%08x" % (crash_node.count, crashes[0].exception_module, crash_node.id)
graph.add_node(crash_node)
print "[%d] %s" % (len(crashes), synopsis)
print "\t",
for crash in crashes:
if graph:
last = crash_node.id
for entry in crash.stack_unwind:
address = long(entry.split(":")[1], 16)
n = graph.find_node("id", address)
if not n:
n = pgraph.node(address)
n.count = 1
n.label = "[%d] %s" % (n.count, entry)
graph.add_node(n)
else:
n.count += 1
n.label = "[%d] %s" % (n.count, entry)
edge = pgraph.edge(n.id, last)
graph.add_edge(edge)
last = n.id
print "%s," % crash.extra,
print "\n"
if graph:
fh = open("%s.udg" % graph_name, "w+")
fh.write(graph.render_graph_udraw())
fh.close()