1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """debugging helper code
20 """
21
22 import linecache
23 import gc
24 import re
25 import sys
26 import types
27
28 from twisted.python.reflect import filenameToModuleName
29
30 __version__ = "$Rev: 7162 $"
31 _tracing = 0
32 _indent = ''
33
34
35 -def trace_start(func_filter=None, ignore_files_re=None, print_returns=False,
36 write=None):
37 global _tracing, _indent
38
39 if func_filter:
40 func_filter = re.compile(func_filter)
41
42 if ignore_files_re:
43 ignore_files_re = re.compile(ignore_files_re)
44
45 if not write:
46
47 def write(indent, str, *args):
48 print (indent + str) % args
49
50 def do_trace(frame, event, arg):
51 global _tracing, _indent
52
53 if not _tracing:
54 print '[tracing stopped]'
55 return None
56
57 co = frame.f_code
58
59 if event == 'line':
60 return do_trace
61 if func_filter and not func_filter.search(co.co_name):
62 return None
63 if ignore_files_re and ignore_files_re.search(co.co_filename):
64 return None
65 elif event == 'call' or event == 'c_call':
66 if co.co_name == '?':
67 return None
68 module = filenameToModuleName(co.co_filename)
69 write(_indent, '%s:%d:%s():', module, frame.f_lineno, co.co_name)
70 _indent += ' '
71 return do_trace
72 elif event == 'return' or event == 'c_return':
73 if print_returns:
74 write(_indent, 'return %r', arg)
75 _indent = _indent[:-2]
76 return None
77 elif event == 'exception' or event == 'c_exception':
78 if arg:
79 write(_indent, 'Exception: %s:%d: %s (%s)', co.co_filename,
80 frame.f_lineno, arg[0].__name__, arg[1])
81 else:
82 write(_indent, 'Exception: (from C)')
83 return do_trace
84 else:
85 write(_indent, 'unknown event: %s', event)
86 return None
87
88 _tracing += 1
89 if _tracing == 1:
90 assert _indent == ''
91 sys.settrace(do_trace)
92
93
101
102
104 f = sys._getframe(1)
105 output = []
106 while f:
107 co = f.f_code
108 filename = co.co_filename
109 lineno = f.f_lineno
110 name = co.co_name
111 linecache.checkcache(filename)
112 line = linecache.getline(filename, lineno)
113
114 if f.f_locals:
115 for k, v in f.f_locals.items():
116 output.append(' %s = %r\n' % (k, v))
117 output.append(' Locals:\n')
118 if line:
119 output.append(' %s\n' % line.strip())
120 output.append(' File "%s", line %d, in %s\n' % (
121 filename, lineno, name))
122 f = f.f_back
123 output.reverse()
124 if handle is None:
125 handle = sys.stdout
126 for line in output:
127 handle.write(line)
128
129
131
133 known = {}
134
135
136
137
138
139
140
141
142 from twisted.internet import reactor
143
144 def sample():
145 gc.collect()
146 for o in gc.garbage:
147 if o not in known:
148 known[o] = True
149 self.uncollectable(o)
150 reactor.callLater(period, sample)
151
152 reactor.callLater(period, sample)
153
155 print '\nUncollectable object cycle in gc.garbage:'
156
157 print "Parents:"
158 self._printParents(obj, 2)
159 print "Kids:"
160 self._printKids(obj, 2)
161
163 print indent, self._shortRepr(obj)
164 if level > 0:
165 for p in gc.get_referrers(obj):
166 self._printParents(p, level - 1, indent + ' ')
167
169 print indent, self._shortRepr(obj)
170 if level > 0:
171 for kid in gc.get_referents(obj):
172 self._printKids(kid, level - 1, indent + ' ')
173
175 if not isinstance(obj, dict):
176 return '%s %r @ 0x%x' % (type(obj).__name__, obj, id(obj))
177 else:
178 keys = obj.keys()
179 keys.sort()
180 return 'dict with keys %r @ 0x%x' % (keys, id(obj))
181
182
184
185 - def __init__(self, period=10, analyze=None, allocPrint=None):
186 self.period = period
187 self.objset = None
188
189 from sizer import scanner, annotate
190
191 from twisted.internet import reactor
192
193 if analyze is not None:
194 self.analyze = analyze
195 if allocPrint is not None:
196 self.allocPrint = allocPrint
197
198 def sample():
199 objset = scanner.Objects()
200 annotate.markparents(objset)
201
202 if self.objset:
203 self.analyze(self.objset, objset)
204
205 self.objset = objset
206 reactor.callLater(self.period, sample)
207
208 reactor.callLater(self.period, sample)
209
211 from sizer import operations
212
213 size = 0
214
215 for k in operations.diff(new, old):
216 size -= old[k].size
217
218 allocators = {}
219 diff = operations.diff(old, new)
220 for k in diff:
221 w = new[k]
222 size += w.size
223 if not w.parents:
224 print "Unreferenced object %r, what?" % (w, )
225 for p in w.parents:
226 if id(p.obj) == id(self.__dict__):
227 continue
228 if id(p.obj) not in diff:
229
230 if p not in allocators:
231 allocators[p] = []
232 allocators[p].append(w)
233 print "Total alloc size:", size
234 for p in allocators:
235 if p.obj == old or p.obj == new:
236 print 'foo'
237 else:
238 self.allocPrint(p, allocators[p])
239 for o in gc.garbage:
240 print '\nUncollectable object cycle in gc.garbage:'
241 self._printCycle(new[id(o)])
242
248
250 print indent, self._wrapperRepr(wrap)
251 if level > 0:
252 for p in wrap.parents:
253 self._printParents(p, level - 1, indent + ' ')
254
256 print indent, self._wrapperRepr(wrap)
257 if level > 0:
258 for kid in wrap.children:
259 self._printKids(kid, level - 1, indent + ' ')
260
262 stack.append(wrap)
263 for p in wrap.parents:
264 if (isinstance(p.obj, types.ModuleType)
265 or isinstance(p.obj, type)
266 or isinstance(p.obj, types.InstanceType)):
267 stack.append(p)
268 return stack
269 if len(wrap.parents) == 1:
270 return self._allocStack(wrap.parents[0], stack)
271 return stack
272
274 o = wrap.obj
275 if wrap.type != dict:
276 return '%s %r @ 0x%x' % (wrap.type.__name__, o, id(o))
277 else:
278 keys = o.keys()
279 keys.sort()
280 return 'dict with keys %r @ 0x%x' % (keys, id(o))
281
283 allocStack = self._allocStack(allocator, [])
284
285 print '\nAlloc by ' + self._wrapperRepr(allocStack.pop(0))
286 while allocStack:
287 print ' referenced by ' + self._wrapperRepr(allocStack.pop(0))
288
289 print "%d new %s:" % (len(directAllocs),
290 len(directAllocs) == 1 and "object" or "objects")
291 for wrap in directAllocs:
292 print ' ' + self._wrapperRepr(wrap)
293
294
296 """
297 Get versions of all flumotion modules based on svn Rev keyword.
298 """
299 r = {}
300 for modname in sys.modules:
301 mod = sys.modules[modname]
302 if modname.startswith('flumotion.') and hasattr(mod, "__version__"):
303
304 try:
305 versionnum = int(mod.__version__[6:-2])
306 r[modname] = versionnum
307 except IndexError:
308 pass
309 except ValueError:
310 pass
311
312 return r
313