]> git.ipfire.org Git - ipfire-3.x.git/blob - src/pomona/exception.py
Merge branch 'master' of ssh://ms@git.ipfire.org/pub/git/ipfire-3.x
[ipfire-3.x.git] / src / pomona / exception.py
1
2 import bdb
3 import os, sys, signal, types
4 from cPickle import Pickler
5 from string import joinfields
6 import traceback
7
8 import gettext
9 _ = lambda x: gettext.ldgettext("pomona", x)
10
11 import logging
12 log = logging.getLogger("pomona")
13
14 dumpHash = {}
15
16 def dumpClass(instance, fd, level=0, parentkey="", skipList=[]):
17 # protect from loops
18 try:
19 if not dumpHash.has_key(instance):
20 dumpHash[instance] = None
21 else:
22 fd.write("Already dumped\n")
23 return
24 except TypeError:
25 fd.write("Cannot dump object\n")
26 return
27
28 if (instance.__class__.__dict__.has_key("__str__") or
29 instance.__class__.__dict__.has_key("__repr__")):
30 fd.write("%s\n" % (instance,))
31 return
32 fd.write("%s instance, containing members:\n" %
33 (instance.__class__.__name__))
34 pad = ' ' * ((level) * 2)
35
36 for key, value in instance.__dict__.items():
37 if parentkey != "":
38 curkey = parentkey + "." + key
39 else:
40 curkey = key
41
42 # Don't dump objects that are in our skip list, though ones that are
43 # None are probably okay.
44 if eval("instance.%s is not None" % key) and \
45 eval("id(instance.%s)" % key) in skipList:
46 continue
47
48 if type(value) == types.ListType:
49 fd.write("%s%s: [" % (pad, curkey))
50 first = 1
51 for item in value:
52 if not first:
53 fd.write(", ")
54 else:
55 first = 0
56 if type(item) == types.InstanceType:
57 dumpClass(item, fd, level + 1, skipList=skipList)
58 else:
59 fd.write("%s" % (item,))
60 fd.write("]\n")
61 elif type(value) == types.DictType:
62 fd.write("%s%s: {" % (pad, curkey))
63 first = 1
64 for k, v in value.items():
65 if not first:
66 fd.write(", ")
67 else:
68 first = 0
69 if type(k) == types.StringType:
70 fd.write("'%s': " % (k,))
71 else:
72 fd.write("%s: " % (k,))
73 if type(v) == types.InstanceType:
74 dumpClass(v, fd, level + 1, parentkey = curkey, skipList=skipList)
75 else:
76 fd.write("%s" % (v,))
77 fd.write("}\n")
78 elif type(value) == types.InstanceType:
79 fd.write("%s%s: " % (pad, curkey))
80 dumpClass(value, fd, level + 1, parentkey=curkey, skipList=skipList)
81 else:
82 fd.write("%s%s: %s\n" % (pad, curkey, value))
83
84 def dumpException(out, text, tb, pomona):
85 skipList = []
86 idSkipList = []
87
88 # Catch attributes that do not exist at the time we do the exception dump
89 # and ignore them.
90 for k in skipList:
91 try:
92 eval("idSkipList.append(id(%s))" % k)
93 except:
94 pass
95
96 p = Pickler(out)
97
98 out.write(text)
99
100 trace = tb
101 if trace is not None:
102 while trace.tb_next:
103 trace = trace.tb_next
104 frame = trace.tb_frame
105 out.write("\nLocal variables in innermost frame:\n")
106 try:
107 for (key, value) in frame.f_locals.items():
108 out.write("%s: %s\n" % (key, value))
109 except:
110 pass
111
112 try:
113 out.write("\n\n")
114 dumpClass(pomona, out, skipList=idSkipList)
115 except:
116 out.write("\nException occurred during state dump:\n")
117 traceback.print_exc(None, out)
118
119 for file in ("/root/syslog", "/root/pomona.log", "/root/install.log"):
120 try:
121 f = open(file, 'r')
122 line = "\n\n%s:\n" % (file,)
123 while line:
124 out.write(line)
125 line = f.readline()
126 f.close()
127 except IOError:
128 pass
129 except:
130 out.write("\nException occurred during %s file copy:\n" % (file,))
131 traceback.print_exc(None, out)
132
133 # Reverse the order that tracebacks are printed so people will hopefully quit
134 # giving us the least useful part of the exception in bug reports.
135 def formatException(type, value, tb):
136 lst = traceback.format_tb(tb)
137 lst.reverse()
138 lst.insert(0, 'Traceback (most recent call first):\n')
139 lst.extend(traceback.format_exception_only(type, value))
140 return lst
141
142 def handleException(pomona, (type, value, tb)):
143 if isinstance(value, bdb.BdbQuit):
144 sys.exit(1)
145
146 # restore original exception handler
147 sys.excepthook = sys.__excepthook__
148
149 # get traceback information
150 list = formatException(type, value, tb)
151 text = joinfields(list, "")
152
153 # save to local storage first
154 out = open("/tmp/instdump.txt", "w")
155 dumpException(out, text, tb, pomona)
156 out.close()
157
158 win = pomona.intf.exceptionWindow(text, "/tmp/instdump.txt")
159 if not win:
160 pomona.intf.__del__()
161 os.kill(os.getpid(), signal.SIGKILL)
162
163 while 1:
164 win.run()
165 rc = win.getrc()
166
167 if rc == 0:
168 pomona.intf.__del__()
169 os.kill(os.getpid(), signal.SIGKILL)