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: 6982 $"
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 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
99
101 f = sys._getframe(1)
102 output = []
103 while f:
104 co = f.f_code
105 filename = co.co_filename
106 lineno = f.f_lineno
107 name = co.co_name
108 linecache.checkcache(filename)
109 line = linecache.getline(filename, lineno)
110
111 if f.f_locals:
112 for k, v in f.f_locals.items():
113 output.append(' %s = %r\n' % (k, v))
114 output.append(' Locals:\n')
115 if line:
116 output.append(' %s\n' % line.strip())
117 output.append(' File "%s", line %d, in %s\n' % (filename,lineno,name))
118 f = f.f_back
119 output.reverse()
120 if handle is None:
121 handle = sys.stdout
122 for line in output:
123 handle.write(line)
124
127 known = {}
128
129
130
131
132
133
134
135
136 from twisted.internet import reactor
137
138 def sample():
139 gc.collect()
140 for o in gc.garbage:
141 if o not in known:
142 known[o] = True
143 self.uncollectable(o)
144 reactor.callLater(period, sample)
145
146 reactor.callLater(period, sample)
147
149 print '\nUncollectable object cycle in gc.garbage:'
150
151 print "Parents:"
152 self._printParents(obj, 2)
153 print "Kids:"
154 self._printKids(obj, 2)
155
157 print indent, self._shortRepr(obj)
158 if level > 0:
159 for p in gc.get_referrers(obj):
160 self._printParents(p, level - 1, indent + ' ')
161
163 print indent, self._shortRepr(obj)
164 if level > 0:
165 for kid in gc.get_referents(obj):
166 self._printKids(kid, level - 1, indent + ' ')
167
169 if not isinstance(obj, dict):
170 return '%s %r @ 0x%x' % (type(obj).__name__, obj, id(obj))
171 else:
172 keys = obj.keys()
173 keys.sort()
174 return 'dict with keys %r @ 0x%x' % (keys, id(obj))
175
177 - def __init__(self, period=10, analyze=None, allocPrint=None):
178 self.period = period
179 self.objset = None
180
181 from sizer import scanner, annotate
182
183 from twisted.internet import reactor
184
185 if analyze is not None:
186 self.analyze = analyze
187 if allocPrint is not None:
188 self.allocPrint = allocPrint
189
190 def sample():
191 objset = scanner.Objects()
192 annotate.markparents(objset)
193
194 if self.objset:
195 self.analyze(self.objset, objset)
196
197 self.objset = objset
198 reactor.callLater(self.period, sample)
199
200 reactor.callLater(self.period, sample)
201
203 from sizer import operations
204
205 size = 0
206
207 for k in operations.diff(new, old):
208 size -= old[k].size
209
210 allocators = {}
211 diff = operations.diff(old, new)
212 for k in diff:
213 w = new[k]
214 size += w.size
215 if not w.parents:
216 print "Unreferenced object %r, what?" % (w,)
217 for p in w.parents:
218 if id(p.obj) == id(self.__dict__):
219 continue
220 if id(p.obj) not in diff:
221
222 if p not in allocators:
223 allocators[p] = []
224 allocators[p].append(w)
225 print "Total alloc size:", size
226 for p in allocators:
227 if p.obj == old or p.obj == new:
228 print 'foo'
229 else:
230 self.allocPrint(p, allocators[p])
231 for o in gc.garbage:
232 print '\nUncollectable object cycle in gc.garbage:'
233 self._printCycle(new[id(o)])
234
240
242 print indent, self._wrapperRepr(wrap)
243 if level > 0:
244 for p in wrap.parents:
245 self._printParents(p, level - 1, indent + ' ')
246
248 print indent, self._wrapperRepr(wrap)
249 if level > 0:
250 for kid in wrap.children:
251 self._printKids(kid, level - 1, indent + ' ')
252
254 stack.append(wrap)
255 for p in wrap.parents:
256 if (isinstance(p.obj, types.ModuleType)
257 or isinstance(p.obj, type)
258 or isinstance(p.obj, types.InstanceType)):
259 stack.append(p)
260 return stack
261 if len(wrap.parents) == 1:
262 return self._allocStack(wrap.parents[0], stack)
263 return stack
264
266 o = wrap.obj
267 if wrap.type != dict:
268 return '%s %r @ 0x%x' % (wrap.type.__name__, o, id(o))
269 else:
270 keys = o.keys()
271 keys.sort()
272 return 'dict with keys %r @ 0x%x' % (keys, id(o))
273
275 allocStack = self._allocStack(allocator, [])
276
277 print '\nAlloc by ' + self._wrapperRepr(allocStack.pop(0))
278 while allocStack:
279 print ' referenced by ' + self._wrapperRepr(allocStack.pop(0))
280
281 print "%d new %s:" % (len(directAllocs),
282 len(directAllocs) == 1 and "object" or "objects")
283 for wrap in directAllocs:
284 print ' ' + self._wrapperRepr(wrap)
285
287 """
288 Get versions of all flumotion modules based on svn Rev keyword.
289 """
290 r = {}
291 for modname in sys.modules:
292 mod = sys.modules[modname]
293 if modname.startswith('flumotion.') and hasattr(mod, "__version__"):
294
295 try:
296 versionnum = int(mod.__version__[6:-2])
297 r[modname] = versionnum
298 except IndexError:
299 pass
300 except ValueError:
301 pass
302
303 return r
304