M PyShell.py
M RemoteDebugger.py M rpc.py Fix the incorrect shell exception tracebacks generated when running under debugger control: 1. Use rpc.SocketIO.asynccall() instead of remotecall() to handle the IdbProxy.run() command. 2. Add a 'shell' attribute to RemoteDebugger.IdbProxy to allow setting of ModifiedInterpreter's active_seq attribute from RemoteDebugger code. 3. Cleanup PyShell.ModifiedInterpreter.runcode() and remove ambiguity regarding use of begin/endexecuting(). 4. In runcode() and cleanup_traceback() use 'console' instead of 'file' to denote the entity to which the exception traceback is printed. 5. Enhance cleanup_traceback() so if the traceback is pruned entirely away (the error is in IDLE internals) it will be displayed in its entirety instead. 6. ModifiedInterpreter.runcode() now prints ERROR RPC returns to both console and __stderr__. 7. Make a small tweak to the rpc.py debug messages.
This commit is contained in:
parent
cd5c8c2120
commit
bc2861313c
|
@ -399,16 +399,16 @@ class ModifiedInterpreter(InteractiveInterpreter):
|
|||
self.tkconsole.resetoutput()
|
||||
self.active_seq = None
|
||||
how, what = response
|
||||
file = self.tkconsole.console
|
||||
console = self.tkconsole.console
|
||||
if how == "OK":
|
||||
if what is not None:
|
||||
print >>file, `what`
|
||||
print >>console, `what`
|
||||
elif how == "EXCEPTION":
|
||||
mod, name, args, tb = what
|
||||
print >>file, 'Traceback (most recent call last):'
|
||||
exclude = ("run.py", "rpc.py")
|
||||
self.cleanup_traceback(tb, exclude)
|
||||
traceback.print_list(tb, file=file)
|
||||
print >>console, 'Traceback (most recent call last):'
|
||||
exclude = ("run.py", "rpc.py", "RemoteDebugger.py", "bdb.py")
|
||||
self.cleanup_traceback(tb, exclude, console)
|
||||
traceback.print_list(tb, file=console)
|
||||
# try to reinstantiate the exception, stuff in the args:
|
||||
try:
|
||||
etype = eval(mod + '.' + name)
|
||||
|
@ -419,18 +419,20 @@ class ModifiedInterpreter(InteractiveInterpreter):
|
|||
val = args
|
||||
lines = traceback.format_exception_only(etype, val)
|
||||
for line in lines[:-1]:
|
||||
traceback._print(file, line, '')
|
||||
traceback._print(file, lines[-1], '')
|
||||
traceback._print(console, line, '')
|
||||
traceback._print(console, lines[-1], '')
|
||||
if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
|
||||
self.remote_stack_viewer()
|
||||
elif how == "ERROR":
|
||||
errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
|
||||
print >>sys.__stderr__, errmsg, what
|
||||
print >>file, errmsg, what
|
||||
print >>console, errmsg, what
|
||||
# we received a response to the currently active seq number:
|
||||
self.tkconsole.endexecuting()
|
||||
|
||||
def cleanup_traceback(self, tb, exclude):
|
||||
def cleanup_traceback(self, tb, exclude, console):
|
||||
"Remove excluded traces from beginning/end of tb; get cached lines"
|
||||
orig_tb = tb[:]
|
||||
while tb:
|
||||
for rpcfile in exclude:
|
||||
if tb[0][0].count(rpcfile):
|
||||
|
@ -445,6 +447,11 @@ class ModifiedInterpreter(InteractiveInterpreter):
|
|||
else:
|
||||
break
|
||||
del tb[-1]
|
||||
if len(tb) == 0:
|
||||
# error was in IDLE internals, don't prune!
|
||||
tb[:] = orig_tb[:]
|
||||
print>>sys.__stderr__, "** IDLE Internal Error: ", tb
|
||||
print>>console, "** IDLE Internal Error **"
|
||||
for i in range(len(tb)):
|
||||
fn, ln, nm, line = tb[i]
|
||||
if nm == '?':
|
||||
|
@ -617,31 +624,26 @@ class ModifiedInterpreter(InteractiveInterpreter):
|
|||
warnings.filters[:] = self.save_warnings_filters
|
||||
self.save_warnings_filters = None
|
||||
debugger = self.debugger
|
||||
if not debugger and self.rpcclt is not None:
|
||||
self.tkconsole.beginexecuting()
|
||||
self.active_seq = self.rpcclt.asynccall("exec", "runcode",
|
||||
(code,), {})
|
||||
return
|
||||
self.tkconsole.beginexecuting()
|
||||
try:
|
||||
self.tkconsole.beginexecuting()
|
||||
try:
|
||||
if debugger:
|
||||
debugger.run(code, self.locals)
|
||||
else:
|
||||
exec code in self.locals
|
||||
except SystemExit:
|
||||
if tkMessageBox.askyesno(
|
||||
"Exit?",
|
||||
"Do you want to exit altogether?",
|
||||
default="yes",
|
||||
master=self.tkconsole.text):
|
||||
raise
|
||||
else:
|
||||
self.showtraceback()
|
||||
except:
|
||||
if not debugger and self.rpcclt is not None:
|
||||
self.active_seq = self.rpcclt.asynccall("exec", "runcode",
|
||||
(code,), {})
|
||||
elif debugger:
|
||||
debugger.run(code, self.locals)
|
||||
else:
|
||||
exec code in self.locals
|
||||
except SystemExit:
|
||||
if tkMessageBox.askyesno(
|
||||
"Exit?",
|
||||
"Do you want to exit altogether?",
|
||||
default="yes",
|
||||
master=self.tkconsole.text):
|
||||
raise
|
||||
else:
|
||||
self.showtraceback()
|
||||
finally:
|
||||
self.tkconsole.endexecuting()
|
||||
except:
|
||||
self.showtraceback()
|
||||
|
||||
def write(self, s):
|
||||
"Override base class method"
|
||||
|
|
|
@ -287,19 +287,21 @@ class GUIAdapter:
|
|||
|
||||
class IdbProxy:
|
||||
|
||||
def __init__(self, conn, oid):
|
||||
def __init__(self, conn, shell, oid):
|
||||
self.oid = oid
|
||||
self.conn = conn
|
||||
self.shell = shell
|
||||
|
||||
def call(self, methodname, *args, **kwargs):
|
||||
##print "call %s %s %s" % (methodname, args, kwargs)
|
||||
##print "**IdbProxy.call %s %s %s" % (methodname, args, kwargs)
|
||||
value = self.conn.remotecall(self.oid, methodname, args, kwargs)
|
||||
##print "return %s" % `value`
|
||||
##print "**IdbProxy.call %s returns %s" % (methodname, `value`)
|
||||
return value
|
||||
|
||||
def run(self, cmd, locals):
|
||||
# Ignores locals on purpose!
|
||||
self.call("run", cmd)
|
||||
seq = self.conn.asynccall(self.oid, "run", (cmd,), {})
|
||||
self.shell.interp.active_seq = seq
|
||||
|
||||
def get_stack(self, frame, tbid):
|
||||
# passing frame and traceback IDs, not the objects themselves
|
||||
|
@ -352,7 +354,7 @@ def start_remote_debugger(rpcclt, pyshell):
|
|||
|
||||
idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\
|
||||
(gui_adap_oid,), {})
|
||||
idb_proxy = IdbProxy(rpcclt, idb_adap_oid)
|
||||
idb_proxy = IdbProxy(rpcclt, pyshell, idb_adap_oid)
|
||||
gui = Debugger.Debugger(pyshell, idb_proxy)
|
||||
gui_adap = GUIAdapter(rpcclt, gui)
|
||||
rpcclt.register(gui_adap_oid, gui_adap)
|
||||
|
|
|
@ -361,9 +361,10 @@ class SocketIO:
|
|||
seq, resq = message
|
||||
self.debug("pollresponse:%d:myseq:%s" % (seq, myseq))
|
||||
if resq[0] == "call":
|
||||
self.debug("pollresponse:%d:call_localcall" % seq)
|
||||
self.debug("pollresponse:%d:localcall:call:" % seq)
|
||||
response = self.localcall(resq)
|
||||
self.debug("pollresponse:%d:response:%s" % (seq, response))
|
||||
self.debug("pollresponse:%d:localcall:response:%s"
|
||||
% (seq, response))
|
||||
self.putmessage((seq, response))
|
||||
continue
|
||||
elif seq == myseq:
|
||||
|
|
Loading…
Reference in New Issue