Salome HOME
PN vielles macros
[tools/eficas.git] / Misc / Trace.py
index 9aac3d2b7c3fd966b4f9060e40ba8a98b3e165eb..a729ff0166e94b0b85b4e6f1aed0ef92b66c0b52 100644 (file)
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 """
     Ce module sert à tracer les appels aux methodes pendant
     l'exécution.
 """
 import sys
 
-def begin_trace():
+# Variables globales
+def _filter(frame):
+  return 0
+filter=_filter
+
+_upcall=0
+_call=1
+_return=0
+_exception=1
+_line=0
+
+# Paramètres
+cara="+"
+ldec=1
+
+def begin_trace(filtre=None,upcall=0):
+     global _upcall,filter
+     if filtre: filter=filtre
+     _upcall=upcall
      sys.settrace(trace_dispatch)
 
 def end_trace():
+     global _upcall,filter
+     filter=_filter
+     _upcall=0
      sys.settrace(None)
 
+def compute_level(frame):
+   """Calcule le niveau dans la pile d'execution"""
+   level=0
+   while frame is not None:
+      frame=frame.f_back
+      level=level+1
+   return level-1
+
+def upcall():
+    frame=sys._getframe(1)
+    level=compute_level(frame)
+    print level*cara,frame.f_code.co_name, " : ",frame.f_code.co_filename,frame.f_lineno
+    frame=frame.f_back
+    print level*' ',"-> appele par : ",frame.f_code.co_name,frame.f_code.co_filename,frame.f_lineno
+    
 def dispatch_call(frame, arg):
      """ Cette fonction est appelée par trace_dispatch
          pour tracer les appels à des fonctions ou méthodes
      """
+     try:
+       level = ldec*(compute_level(frame)-1)
+       name = frame.f_code.co_name
+       if not name: name = '???'
+       if not filter(frame):
+           print level*cara +' call', name, frame.f_code.co_filename,frame.f_lineno
+           if _upcall:
+              f_back=frame.f_back
+              print level*' ',"-> appele par : ",f_back.f_code.co_name,f_back.f_code.co_filename,f_back.f_lineno
+     except:
+       print "Pb dans dispatch_call: ",frame
+     return trace_dispatch
+
+def dispatch_exception(frame, arg):
+     """ Cette fonction est appelée par trace_dispatch
+         pour tracer les exceptions
+     """
+     try:
+       dec = cara*ldec*(compute_level(frame)+0)
+       name = frame.f_code.co_name
+       if not name: name = '???'
+       if not filter(frame):
+          print dec,name,'exception',frame.f_code.co_filename,frame.f_lineno,arg[0],arg[1]
+     except:
+       print "Pb dans dispatch_exception: ",frame
+     return trace_dispatch
+
+def dispatch_return(frame, arg):
+     """ Cette fonction est appelée par trace_dispatch
+         pour tracer les retours de fonction
+     """
+     dec = cara*ldec*compute_level(frame)
+     name = frame.f_code.co_name
+     if not name: name = '???'
+     print dec,name,'return', arg
+     return trace_dispatch
+
+def dispatch_line(frame, arg):
+     """ Cette fonction est appelée par trace_dispatch
+         pour tracer les lignes de source
+     """
+     import linecache
      name = frame.f_code.co_name
      if not name: name = '???'
-     print '+++ call', name, arg
+     fn=frame.f_code.co_filename
+     line = linecache.getline(fn, frame.f_lineno)
+     dec = cara*ldec*compute_level(frame)
+     print dec,name,':',line.strip(),frame.f_lineno
+     return trace_dispatch
 
 def trace_dispatch(frame,event,arg):
      """ Cette fonction sert à tracer tous les appels
          à des fonctions ou à des méthodes.
      """
-     if event == 'call':
-        return dispatch_call(frame, arg)
+     if _call and event == 'call': return dispatch_call(frame, arg)
+     if _return and event == 'return': return dispatch_return(frame, arg)
+     if _line and event == 'line': return dispatch_line(frame, arg)
+     if _exception and event == 'exception': return dispatch_exception(frame, arg)
      return trace_dispatch
 
+def a(x):
+   b(x)
+
+def b(x):
+   return x
+
+def d(x):
+   return 1/x
+
+def e():
+   try:
+     c=1/0
+   except:
+     pass
+
+def f():
+   try:
+     c=1/0
+   except:
+     b(10)
+     raise
+
+def g():
+   try:
+      f()
+   except:
+      pass
+
+def _test():
+   def filter(frame):
+       return not frame.f_code.co_name == 'a'
+
+   begin_trace(filtre=filter,upcall=1)
+   a(5)
+   try:
+     d(0)
+   except:
+     pass
+   b(4)
+   g()
+   e()  
+   end_trace()
+   b(3)
+
+if __name__ == "__main__":
+    _test()
+