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