## ## some useful exception and reference leak count and traceback routines ## care of Sam Rushing (www.nightmare.com) of Medusa fame... ## import string import sys whoCallsError = "whoCallsError" #-------------------------------------------------------------- # Example use: # # import who_calls # sys.stderr.write("%s\n" % who_calls.pretty_who_calls()) # #-------------------------------------------------------------- def test(): for i in range(1,1000): pretty_who_calls() print_top_100() def who_calls_helper(): tinfo = [] exc_info = sys.exc_info() f = exc_info[2].tb_frame.f_back while f: tinfo.append ( f.f_code.co_filename, f.f_code.co_name, f.f_lineno ) f = f.f_back del exc_info return tinfo def who_calls(): try: raise whoCallsError except whoCallsError: tinfo = who_calls_helper() return tinfo def pretty_who_calls(): info = who_calls() buf = [] for file,function,line in info[1:]: buf.append(" %s(%s): %s()" % (file,line,function)) return string.join(buf,"\n") # --------------------------------------------------------------------------- # used for debugging. # --------------------------------------------------------------------------- def compact_traceback (): t,v,tb = sys.exc_info() tbinfo = [] while 1: tbinfo.append ( tb.tb_frame.f_code.co_filename, tb.tb_frame.f_code.co_name, str(tb.tb_lineno) ) tb = tb.tb_next if not tb: break # just to be safe del tb file, function, line = tbinfo[-1] info = '[' + string.join ( map ( lambda x: string.join (x, '|'), tbinfo ), '] [' ) + ']' return (file, function, line), str(t), str(v), info ## ---------------------------------------------------- ## Refcount printing import sys import types def get_refcounts(): d = {} sys.modules # collect all classes for modname,m in sys.modules.items(): for sym in dir(m): o = getattr (m, sym) if type(o) is types.ClassType: d["%s:%s" % (modname,o.__name__)] = sys.getrefcount (o) # sort by refcount pairs = map (lambda x: (x[1],x[0]), d.items()) pairs.sort() pairs.reverse() return pairs def print_top_100(): print_top_N(100) def print_top_N(N): for n, c in get_refcounts()[:N]: sys.stderr.write('%10d %s\n' % (n, c))