$search
00001 00002 # who_calls.py 00003 # by Sam Rushing for Medusa 00004 00005 import string 00006 import sys 00007 00008 from log import * 00009 00010 whoCallsError = "whoCallsError" 00011 00012 #-------------------------------------------------------------- 00013 # Example use: 00014 # 00015 # import who_calls 00016 # log(who_calls.pretty_who_calls()) 00017 # 00018 #-------------------------------------------------------------- 00019 00020 def test(): 00021 for i in range(1,1000): 00022 pretty_who_calls() 00023 00024 print_top_100() 00025 00026 def who_calls_helper(): 00027 tinfo = [] 00028 exc_info = sys.exc_info() 00029 00030 f = exc_info[2].tb_frame.f_back 00031 while f: 00032 tinfo.append ( ( 00033 f.f_code.co_filename, 00034 f.f_code.co_name, 00035 f.f_lineno ) 00036 ) 00037 f = f.f_back 00038 00039 del exc_info 00040 return tinfo 00041 00042 00043 def who_calls(): 00044 try: 00045 raise whoCallsError 00046 except whoCallsError: 00047 tinfo = who_calls_helper() 00048 return tinfo 00049 00050 def pretty_who_calls(strip=0): 00051 info = who_calls() 00052 buf = [] 00053 00054 for file,function,line in info[1 + strip:]: 00055 buf.append(" %s(%s): %s()" % (file,line,function)) 00056 00057 return string.join(buf,"\n") 00058 00059 # --------------------------------------------------------------------------- 00060 # used for debugging. 00061 # --------------------------------------------------------------------------- 00062 00063 def compact_traceback (): 00064 t,v,tb = sys.exc_info() 00065 tbinfo = [] 00066 if tb is None: 00067 # this should never happen, but then again, lots of things 00068 # should never happen but do. 00069 return (('','',''), str(t), str(v), 'traceback is None!!!') 00070 while 1: 00071 tbinfo.append ( 00072 tb.tb_frame.f_code.co_filename, 00073 tb.tb_frame.f_code.co_name, 00074 str(tb.tb_lineno) 00075 ) 00076 tb = tb.tb_next 00077 if not tb: 00078 break 00079 00080 # just to be safe 00081 del tb 00082 00083 file, function, line = tbinfo[-1] 00084 info = '[' + string.join ( 00085 map ( 00086 lambda x: string.join (x, '|'), 00087 tbinfo 00088 ), 00089 '] [' 00090 ) + ']' 00091 00092 return (file, function, line), str(t), str(v), info 00093 00094 ## ---------------------------------------------------- 00095 ## Refcount printing 00096 00097 import sys 00098 import types 00099 00100 def real_get_refcounts(base = None, set_base = 0): 00101 d = {} 00102 sys.modules 00103 # collect all classes 00104 for modname,m in sys.modules.items(): 00105 for sym in dir(m): 00106 o = getattr (m, sym) 00107 if type(o) is types.ClassType: 00108 name = "%s:%s" % (modname,o.__name__) 00109 cnt = sys.getrefcount (o) 00110 if base: 00111 if set_base: 00112 base[name] = cnt 00113 elif cnt > base.get(name, 0): 00114 d[name] = cnt - base.get(name, 0) 00115 else: 00116 d[name] = cnt 00117 return d 00118 00119 def get_refcounts(base=None): 00120 d = real_get_refcounts(base = base) 00121 # sort by refcount 00122 pairs = map (lambda x: (x[1],x[0]), d.items()) 00123 pairs.sort() 00124 pairs.reverse() 00125 return pairs 00126 00127 REFCOUNTS = {} 00128 00129 def set_refcount_base(): 00130 global REFCOUNTS 00131 real_get_refcounts(REFCOUNTS, set_base = 1) 00132 00133 def print_top_100(): 00134 print_top_N(100) 00135 00136 def print_top_N(N): 00137 global REFCOUNTS 00138 for n, c in get_refcounts(REFCOUNTS)[:N]: 00139 log('%10d %s' % (n, c)) 00140 00141