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