Home | History | Annotate | Download | only in base
      1 
      2 # who_calls.py
      3 # by Sam Rushing for Medusa
      4 
      5 import string
      6 import sys
      7 
      8 from log import *
      9 
     10 whoCallsError = "whoCallsError"
     11 
     12 #--------------------------------------------------------------
     13 # Example use:
     14 #
     15 # import who_calls
     16 # log(who_calls.pretty_who_calls())
     17 #
     18 #--------------------------------------------------------------
     19 
     20 def test():
     21   for i in range(1,1000):
     22     pretty_who_calls()
     23 
     24   print_top_100()
     25 
     26 def 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 
     43 def who_calls():
     44   try:
     45     raise whoCallsError
     46   except whoCallsError:
     47     tinfo = who_calls_helper()
     48   return tinfo
     49 
     50 def 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 
     63 def 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 		
     97 import sys
     98 import types
     99 
    100 def 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 
    119 def 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 
    127 REFCOUNTS = {}
    128 
    129 def set_refcount_base():
    130     global REFCOUNTS
    131     real_get_refcounts(REFCOUNTS, set_base = 1)
    132 
    133 def print_top_100():
    134         print_top_N(100)
    135 
    136 def 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