• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2# who_calls.py
3# by Sam Rushing for Medusa
4
5import string
6import sys
7
8from log import *
9
10whoCallsError = "whoCallsError"
11
12#--------------------------------------------------------------
13# Example use:
14#
15# import who_calls
16# log(who_calls.pretty_who_calls())
17#
18#--------------------------------------------------------------
19
20def test():
21  for i in range(1,1000):
22    pretty_who_calls()
23
24  print_top_100()
25
26def who_calls_helper():
27  tinfo = []
28  exc_info = sys.exc_info()
29
30  f = exc_info[2].tb_frame.f_back
31  while f:
32	  tinfo.append ( (
33		  f.f_code.co_filename,
34		  f.f_code.co_name,
35		  f.f_lineno )
36		  )
37	  f = f.f_back
38
39  del exc_info
40  return tinfo
41
42
43def who_calls():
44  try:
45    raise whoCallsError
46  except whoCallsError:
47    tinfo = who_calls_helper()
48  return tinfo
49
50def pretty_who_calls(strip=0):
51	info = who_calls()
52	buf = []
53
54	for file,function,line in info[1 + strip:]:
55		buf.append("   %s(%s): %s()" % (file,line,function))
56
57	return string.join(buf,"\n")
58
59# ---------------------------------------------------------------------------
60# used for debugging.
61# ---------------------------------------------------------------------------
62
63def compact_traceback ():
64	t,v,tb = sys.exc_info()
65	tbinfo = []
66	if tb is None:
67		# this should never happen, but then again, lots of things
68		# should never happen but do.
69		return (('','',''), str(t), str(v), 'traceback is None!!!')
70	while 1:
71		tbinfo.append (
72			tb.tb_frame.f_code.co_filename,
73			tb.tb_frame.f_code.co_name,
74			str(tb.tb_lineno)
75			)
76		tb = tb.tb_next
77		if not tb:
78			break
79
80	# just to be safe
81	del tb
82
83	file, function, line = tbinfo[-1]
84	info = '[' + string.join (
85		map (
86			lambda x: string.join (x, '|'),
87			tbinfo
88			),
89		'] ['
90		) + ']'
91
92	return (file, function, line), str(t), str(v), info
93
94## ----------------------------------------------------
95## Refcount printing
96
97import sys
98import types
99
100def real_get_refcounts(base = None, set_base = 0):
101    d = {}
102    sys.modules
103    # collect all classes
104    for modname,m in sys.modules.items():
105        for sym in dir(m):
106            o = getattr (m, sym)
107            if type(o) is types.ClassType:
108                name = "%s:%s" % (modname,o.__name__)
109                cnt = sys.getrefcount (o)
110                if base:
111                    if set_base:
112                        base[name] = cnt
113                    elif cnt > base.get(name, 0):
114                        d[name] = cnt - base.get(name, 0)
115                else:
116                    d[name] = cnt
117    return d
118
119def get_refcounts(base=None):
120        d = real_get_refcounts(base = base)
121        # sort by refcount
122        pairs = map (lambda x: (x[1],x[0]), d.items())
123        pairs.sort()
124        pairs.reverse()
125        return pairs
126
127REFCOUNTS = {}
128
129def set_refcount_base():
130    global REFCOUNTS
131    real_get_refcounts(REFCOUNTS, set_base = 1)
132
133def print_top_100():
134        print_top_N(100)
135
136def print_top_N(N):
137    global REFCOUNTS
138    for n, c in get_refcounts(REFCOUNTS)[:N]:
139       log('%10d %s' % (n, c))
140
141
142