1 """SCons.Debug
2
3 Code for debugging SCons internal things. Not everything here is
4 guaranteed to work all the way back to Python 1.5.2, and shouldn't be
5 needed by most users.
6
7 """
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 __revision__ = "src/engine/SCons/Debug.py 3842 2008/12/20 22:59:52 scons"
33
34 import os
35 import string
36 import sys
37
38
39 try:
40 import weakref
41 except ImportError:
44 else:
51
52
53
54 tracked_classes = {}
55
63
67
71
79
81 for classname in string_to_classes(classes):
82 file.write('\n%s:\n' % classname)
83 for ref in tracked_classes[classname]:
84 obj = ref()
85 if obj is not None:
86 file.write(' %s:\n' % obj)
87 for key, value in obj.__dict__.items():
88 file.write(' %20s : %s\n' % (key, value))
89
90
91
92 if sys.platform[:5] == "linux":
93
98 else:
99 try:
100 import resource
101 except ImportError:
102 try:
103 import win32process
104 import win32api
105 except ImportError:
108 else:
110 process_handle = win32api.GetCurrentProcess()
111 memory_info = win32process.GetProcessMemoryInfo( process_handle )
112 return memory_info['PeakWorkingSetSize']
113 else:
115 res = resource.getrusage(resource.RUSAGE_SELF)
116 return res[4]
117
118
120 import traceback
121 if not backlist:
122 backlist = [0]
123 result = []
124 for back in backlist:
125 tb = traceback.extract_stack(limit=3+back)
126 key = tb[0][:3]
127 result.append('%s:%d(%s)' % func_shorten(key))
128 return result
129
130 caller_bases = {}
131 caller_dicts = {}
132
133
135 import traceback
136 tb = traceback.extract_stack(limit=3+back)
137 tb.reverse()
138 callee = tb[1][:3]
139 caller_bases[callee] = caller_bases.get(callee, 0) + 1
140 for caller in tb[2:]:
141 caller = callee + caller[:3]
142 try:
143 entry = caller_dicts[callee]
144 except KeyError:
145 caller_dicts[callee] = entry = {}
146 entry[caller] = entry.get(caller, 0) + 1
147 callee = caller
148
149
160
161
169
170 shorten_list = [
171 ( '/scons/SCons/', 1),
172 ( '/src/engine/SCons/', 1),
173 ( '/usr/lib/python', 0),
174 ]
175
176 if os.sep != '/':
179 shorten_list = map(platformize, shorten_list)
180 del platformize
181
183 f = func_tuple[0]
184 for t in shorten_list:
185 i = string.find(f, t[0])
186 if i >= 0:
187 if t[1]:
188 i = i + len(t[0])
189 return (f[i:],)+func_tuple[1:]
190 return func_tuple
191
192
193 TraceFP = {}
194 if sys.platform == 'win32':
195 TraceDefault = 'con'
196 else:
197 TraceDefault = '/dev/tty'
198
199 -def Trace(msg, file=None, mode='w'):
200 """Write a trace message to a file. Whenever a file is specified,
201 it becomes the default for the next call to Trace()."""
202 global TraceDefault
203 if file is None:
204 file = TraceDefault
205 else:
206 TraceDefault = file
207 try:
208 fp = TraceFP[file]
209 except KeyError:
210 try:
211 fp = TraceFP[file] = open(file, mode)
212 except TypeError:
213
214 fp = file
215 fp.write(msg)
216 fp.flush()
217