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