blob: 0442ba86e2e58fa78cd33ed0f830294ae847e138 [file] [log] [blame]
Guido van Rossum217a5fa1990-12-26 15:40:07 +00001# Print tracebacks, with a dump of local variables.
2# Also an interactive stack trace browser.
3
4import sys
Guido van Rossum9542c581992-01-12 23:27:56 +00005import os
Guido van Rossum217a5fa1990-12-26 15:40:07 +00006from stat import *
7import string
Guido van Rossum9542c581992-01-12 23:27:56 +00008import linecache
Guido van Rossum217a5fa1990-12-26 15:40:07 +00009
10def br(): browser(sys.last_traceback)
11
12def tb(): printtb(sys.last_traceback)
13
14def browser(tb):
15 if not tb:
16 print 'No traceback.'
17 return
18 tblist = []
19 while tb:
20 tblist.append(tb)
21 tb = tb.tb_next
22 ptr = len(tblist)-1
23 tb = tblist[ptr]
24 while 1:
25 if tb <> tblist[ptr]:
26 tb = tblist[ptr]
27 print `ptr` + ':',
28 printtbheader(tb)
29 try:
30 line = raw_input('TB: ')
31 except KeyboardInterrupt:
32 print '\n[Interrupted]'
33 break
34 except EOFError:
35 print '\n[EOF]'
36 break
37 cmd = string.strip(line)
38 if cmd:
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000039 if cmd == 'quit':
Guido van Rossum217a5fa1990-12-26 15:40:07 +000040 break
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000041 elif cmd == 'list':
Guido van Rossum217a5fa1990-12-26 15:40:07 +000042 browserlist(tb)
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000043 elif cmd == 'up':
Guido van Rossum217a5fa1990-12-26 15:40:07 +000044 if ptr-1 >= 0: ptr = ptr-1
45 else: print 'Bottom of stack.'
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000046 elif cmd == 'down':
Guido van Rossum217a5fa1990-12-26 15:40:07 +000047 if ptr+1 < len(tblist): ptr = ptr+1
48 else: print 'Top of stack.'
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000049 elif cmd == 'locals':
Guido van Rossum217a5fa1990-12-26 15:40:07 +000050 printsymbols(tb.tb_frame.f_locals)
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000051 elif cmd == 'globals':
Guido van Rossum217a5fa1990-12-26 15:40:07 +000052 printsymbols(tb.tb_frame.f_globals)
53 elif cmd in ('?', 'help'):
54 browserhelp()
55 else:
56 browserexec(tb, cmd)
57
58def browserlist(tb):
59 filename = tb.tb_frame.f_code.co_filename
60 lineno = tb.tb_lineno
61 last = lineno
62 first = max(1, last-10)
63 for i in range(first, last+1):
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000064 if i == lineno: prefix = '***' + string.rjust(`i`, 4) + ':'
Guido van Rossum217a5fa1990-12-26 15:40:07 +000065 else: prefix = string.rjust(`i`, 7) + ':'
Guido van Rossum9542c581992-01-12 23:27:56 +000066 line = linecache.getline(filename, i)
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000067 if line[-1:] == '\n': line = line[:-1]
Guido van Rossum217a5fa1990-12-26 15:40:07 +000068 print prefix + line
69
70def browserexec(tb, cmd):
71 locals = tb.tb_frame.f_locals
72 globals = tb.tb_frame.f_globals
73 try:
74 exec(cmd+'\n', globals, locals)
75 except:
76 print '*** Exception:',
Guido van Rossumc7acf2a1995-02-27 13:15:45 +000077 if type(sys.exc_type) == type(''):
78 print sys.exc_type,
79 else:
80 print sys.exc_type.__name__,
Guido van Rossum217a5fa1990-12-26 15:40:07 +000081 if sys.exc_value <> None:
82 print ':', sys.exc_value,
83 print
84 print 'Type help to get help.'
85
86def browserhelp():
87 print
88 print ' This is the traceback browser. Commands are:'
89 print ' up : move one level up in the call stack'
90 print ' down : move one level down in the call stack'
91 print ' locals : print all local variables at this level'
92 print ' globals : print all global variables at this level'
93 print ' list : list source code around the failure'
94 print ' help : print help (what you are reading now)'
95 print ' quit : back to command interpreter'
96 print ' Typing any other 1-line statement will execute it'
97 print ' using the current level\'s symbol tables'
98 print
99
100def printtb(tb):
101 while tb:
102 print1tb(tb)
103 tb = tb.tb_next
104
105def print1tb(tb):
106 printtbheader(tb)
107 if tb.tb_frame.f_locals is not tb.tb_frame.f_globals:
108 printsymbols(tb.tb_frame.f_locals)
109
110def printtbheader(tb):
111 filename = tb.tb_frame.f_code.co_filename
112 lineno = tb.tb_lineno
113 info = '"' + filename + '"(' + `lineno` + ')'
Guido van Rossum9542c581992-01-12 23:27:56 +0000114 line = linecache.getline(filename, lineno)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000115 if line:
116 info = info + ': ' + string.strip(line)
117 print info
118
119def printsymbols(d):
120 keys = d.keys()
121 keys.sort()
122 for name in keys:
123 print ' ' + string.ljust(name, 12) + ':',
124 printobject(d[name], 4)
125 print
126
127def printobject(v, maxlevel):
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +0000128 if v == None:
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000129 print 'None',
130 elif type(v) in (type(0), type(0.0)):
131 print v,
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +0000132 elif type(v) == type(''):
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000133 if len(v) > 20:
134 print `v[:17] + '...'`,
135 else:
136 print `v`,
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +0000137 elif type(v) == type(()):
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000138 print '(',
139 printlist(v, maxlevel)
140 print ')',
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +0000141 elif type(v) == type([]):
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000142 print '[',
143 printlist(v, maxlevel)
144 print ']',
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +0000145 elif type(v) == type({}):
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000146 print '{',
147 printdict(v, maxlevel)
148 print '}',
149 else:
150 print v,
151
152def printlist(v, maxlevel):
153 n = len(v)
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +0000154 if n == 0: return
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000155 if maxlevel <= 0:
156 print '...',
157 return
158 for i in range(min(6, n)):
159 printobject(v[i], maxlevel-1)
160 if i+1 < n: print ',',
161 if n > 6: print '...',
162
163def printdict(v, maxlevel):
164 keys = v.keys()
165 n = len(keys)
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +0000166 if n == 0: return
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000167 if maxlevel <= 0:
168 print '...',
169 return
170 keys.sort()
171 for i in range(min(6, n)):
172 key = keys[i]
173 print `key` + ':',
174 printobject(v[key], maxlevel-1)
175 if i+1 < n: print ',',
176 if n > 6: print '...',