Salome HOME
PN vielles macros
[tools/eficas.git] / Misc / Trace.py
1 # -*- coding: utf-8 -*-
2 """
3     Ce module sert à tracer les appels aux methodes pendant
4     l'exécution.
5     Mode d'emploi :
6     Au début de la zone à tracer faire : Trace.begin_trace()
7     à la fin de la zone faire : Trace.end_trace()
8
9 """
10 import sys
11
12 # Variables globales
13 def _filter(frame):
14   return 0
15 filter=_filter
16
17 _upcall=0
18 _call=1
19 _return=0
20 _exception=1
21 _line=0
22
23 # Paramètres
24 cara="+"
25 ldec=1
26
27 def begin_trace(filtre=None,upcall=0):
28      global _upcall,filter
29      if filtre: filter=filtre
30      _upcall=upcall
31      sys.settrace(trace_dispatch)
32
33 def end_trace():
34      global _upcall,filter
35      filter=_filter
36      _upcall=0
37      sys.settrace(None)
38
39 def compute_level(frame):
40    """Calcule le niveau dans la pile d'execution"""
41    level=0
42    while frame is not None:
43       frame=frame.f_back
44       level=level+1
45    return level-1
46
47 def upcall():
48     frame=sys._getframe(1)
49     level=compute_level(frame)
50     print level*cara,frame.f_code.co_name, " : ",frame.f_code.co_filename,frame.f_lineno
51     frame=frame.f_back
52     print level*' ',"-> appele par : ",frame.f_code.co_name,frame.f_code.co_filename,frame.f_lineno
53     
54 def dispatch_call(frame, arg):
55      """ Cette fonction est appelée par trace_dispatch
56          pour tracer les appels à des fonctions ou méthodes
57      """
58      try:
59        level = ldec*(compute_level(frame)-1)
60        name = frame.f_code.co_name
61        if not name: name = '???'
62        if not filter(frame):
63            print level*cara +' call', name, frame.f_code.co_filename,frame.f_lineno
64            if _upcall:
65               f_back=frame.f_back
66               print level*' ',"-> appele par : ",f_back.f_code.co_name,f_back.f_code.co_filename,f_back.f_lineno
67      except:
68        print "Pb dans dispatch_call: ",frame
69      return trace_dispatch
70
71 def dispatch_exception(frame, arg):
72      """ Cette fonction est appelée par trace_dispatch
73          pour tracer les exceptions
74      """
75      try:
76        dec = cara*ldec*(compute_level(frame)+0)
77        name = frame.f_code.co_name
78        if not name: name = '???'
79        if not filter(frame):
80           print dec,name,'exception',frame.f_code.co_filename,frame.f_lineno,arg[0],arg[1]
81      except:
82        print "Pb dans dispatch_exception: ",frame
83      return trace_dispatch
84
85 def dispatch_return(frame, arg):
86      """ Cette fonction est appelée par trace_dispatch
87          pour tracer les retours de fonction
88      """
89      dec = cara*ldec*compute_level(frame)
90      name = frame.f_code.co_name
91      if not name: name = '???'
92      print dec,name,'return', arg
93      return trace_dispatch
94
95 def dispatch_line(frame, arg):
96      """ Cette fonction est appelée par trace_dispatch
97          pour tracer les lignes de source
98      """
99      import linecache
100      name = frame.f_code.co_name
101      if not name: name = '???'
102      fn=frame.f_code.co_filename
103      line = linecache.getline(fn, frame.f_lineno)
104      dec = cara*ldec*compute_level(frame)
105      print dec,name,':',line.strip(),frame.f_lineno
106      return trace_dispatch
107
108 def trace_dispatch(frame,event,arg):
109      """ Cette fonction sert à tracer tous les appels
110          à des fonctions ou à des méthodes.
111      """
112      if _call and event == 'call': return dispatch_call(frame, arg)
113      if _return and event == 'return': return dispatch_return(frame, arg)
114      if _line and event == 'line': return dispatch_line(frame, arg)
115      if _exception and event == 'exception': return dispatch_exception(frame, arg)
116      return trace_dispatch
117
118 def a(x):
119    b(x)
120
121 def b(x):
122    return x
123
124 def d(x):
125    return 1/x
126
127 def e():
128    try:
129      c=1/0
130    except:
131      pass
132
133 def f():
134    try:
135      c=1/0
136    except:
137      b(10)
138      raise
139
140 def g():
141    try:
142       f()
143    except:
144       pass
145
146 def _test():
147    def filter(frame):
148        return not frame.f_code.co_name == 'a'
149
150    begin_trace(filtre=filter,upcall=1)
151    a(5)
152    try:
153      d(0)
154    except:
155      pass
156    b(4)
157    g()
158    e()  
159    end_trace()
160    b(3)
161
162 if __name__ == "__main__":
163     _test()
164