]> git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/ide/activegrid/tool/DebuggerHarness.py
Docview and IDE patch from Morag Hua with fix for bug #1217890
[wxWidgets.git] / wxPython / samples / ide / activegrid / tool / DebuggerHarness.py
1 #----------------------------------------------------------------------------
2 # Name: DebuggerHarness.py
3 # Purpose:
4 #
5 # Author: Matt Fryer
6 #
7 # Created: 7/28/04
8 # CVS-ID: $Id$
9 # Copyright: (c) 2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
12 import bdb
13 import sys
14 import SimpleXMLRPCServer
15 import threading
16 import xmlrpclib
17 import os
18 import types
19 import Queue
20 import traceback
21 import inspect
22 from xml.dom.minidom import getDOMImplementation
23 import atexit
24 import pickle
25 import cStringIO
26 import bz2
27
28 if sys.platform.startswith("win"):
29 import win32api
30 _WINDOWS = True
31 else:
32 _WINDOWS = False
33
34 _VERBOSE = False
35 _DEBUG_DEBUGGER = False
36
37 class Adb(bdb.Bdb):
38
39 def __init__(self, harness, queue):
40 bdb.Bdb.__init__(self)
41 self._harness = harness
42 self._userBreak = False
43 self._queue = queue
44 self._knownCantExpandFiles = {}
45 self._knownExpandedFiles = {}
46
47 def getLongName(self, filename):
48 if not _WINDOWS:
49 return filename
50 if self._knownCantExpandFiles.get(filename):
51 return filename
52 if self._knownExpandedFiles.get(filename):
53 return self._knownExpandedFiles.get(filename)
54 try:
55 newname = win32api.GetLongPathName(filename)
56 self._knownExpandedFiles[filename] = newname
57 return newname
58 except:
59 self._knownCantExpandFiles[filename] = filename
60 return filename
61
62 def canonic(self, orig_filename):
63 if orig_filename == "<" + orig_filename[1:-1] + ">":
64 return orig_filename
65 filename = self.getLongName(orig_filename)
66
67 canonic = self.fncache.get(filename)
68 if not canonic:
69 canonic = os.path.abspath(filename)
70 canonic = os.path.normcase(canonic)
71 self.fncache[filename] = canonic
72 return canonic
73
74
75 # Overriding this so that we continue to trace even if no breakpoints are set.
76 def set_continue(self):
77 self.stopframe = self.botframe
78 self.returnframe = None
79 self.quitting = 0
80
81 def do_clear(self, arg):
82 bdb.Breakpoint.bpbynumber[int(arg)].deleteMe()
83
84 def user_line(self, frame):
85 if self.in_debugger_code(frame):
86 self.set_step()
87 return
88 message = self.__frame2message(frame)
89 self._harness.interaction(message, frame, "")
90
91 def user_call(self, frame, argument_list):
92 if self.in_debugger_code(frame):
93 self.set_step()
94 return
95 if self.stop_here(frame):
96 message = self.__frame2message(frame)
97 self._harness.interaction(message, frame, "")
98
99 def user_return(self, frame, return_value):
100 if self.in_debugger_code(frame):
101 self.set_step()
102 return
103 message = self.__frame2message(frame)
104 self._harness.interaction(message, frame, "")
105
106 def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
107 frame.f_locals['__exception__'] = exc_type, exc_value
108 if type(exc_type) == type(''):
109 exc_type_name = exc_type
110 else:
111 exc_type_name = exc_type.__name__
112 message = "Exception occured: " + repr(exc_type_name) + " See locals.__exception__ for details."
113 traceback.print_exception(exc_type, exc_value, exc_traceback)
114 self._harness.interaction(message, frame, message)
115
116 def in_debugger_code(self, frame):
117 if _DEBUG_DEBUGGER: return False
118 message = self.__frame2message(frame)
119 return message.count('DebuggerHarness') > 0
120
121 def frame2message(self, frame):
122 return self.__frame2message(frame)
123
124 def __frame2message(self, frame):
125 code = frame.f_code
126 filename = code.co_filename
127 lineno = frame.f_lineno
128 basename = os.path.basename(filename)
129 message = "%s:%s" % (basename, lineno)
130 if code.co_name != "?":
131 message = "%s: %s()" % (message, code.co_name)
132 return message
133
134 def runFile(self, fileName):
135 self.reset()
136 #global_dict = {}
137 #global_dict['__name__'] = '__main__'
138 try:
139 fileToRun = open(fileName, mode='r')
140 if _VERBOSE: print "Running file ", fileName
141 sys.settrace(self.trace_dispatch)
142 import __main__
143 exec fileToRun in __main__.__dict__,__main__.__dict__
144 except SystemExit:
145 pass
146 except:
147 tp, val, tb = sys.exc_info()
148 traceback.print_exception(tp, val, tb)
149
150 sys.settrace(None)
151 self.quitting = 1
152 #global_dict.clear()
153
154 def trace_dispatch(self, frame, event, arg):
155 if self.quitting:
156 return # None
157 # Check for ui events
158 self.readQueue()
159 if event == 'line':
160 return self.dispatch_line(frame)
161 if event == 'call':
162 return self.dispatch_call(frame, arg)
163 if event == 'return':
164 return self.dispatch_return(frame, arg)
165 if event == 'exception':
166 return self.dispatch_exception(frame, arg)
167 print 'Adb.dispatch: unknown debugging event:', `event`
168 return self.trace_dispatch
169
170 def readQueue(self):
171 while self._queue.qsize():
172 try:
173 item = self._queue.get_nowait()
174 if item.kill():
175 self._harness.do_exit(kill=True)
176 elif item.breakHere():
177 self._userBreak = True
178 elif item.hasBreakpoints():
179 self.set_all_breakpoints(item.getBreakpoints())
180 except Queue.Empty:
181 pass
182
183 def set_all_breakpoints(self, dict):
184 self.clear_all_breaks()
185 for fileName in dict.keys():
186 lineList = dict[fileName]
187 for lineNumber in lineList:
188
189 if _VERBOSE: print "Setting break at line ", str(lineNumber), " in file ", self.canonic(fileName)
190 self.set_break(fileName, int(lineNumber))
191 return ""
192
193 def stop_here(self, frame):
194 if self._userBreak:
195 return True
196
197
198 # (CT) stopframe may now also be None, see dispatch_call.
199 # (CT) the former test for None is therefore removed from here.
200 if frame is self.stopframe:
201 return True
202 while frame is not None and frame is not self.stopframe:
203 if frame is self.botframe:
204 return True
205 frame = frame.f_back
206 return False
207
208 class BreakNotify(object):
209 def __init__(self, bps=None, break_here=False, kill=False):
210 self._bps = bps
211 self._break_here = break_here
212 self._kill = kill
213
214 def breakHere(self):
215 return self._break_here
216
217 def kill(self):
218 return self._kill
219
220 def getBreakpoints(self):
221 return self._bps
222
223 def hasBreakpoints(self):
224 return (self._bps != None)
225
226 class AGXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
227 def __init__(self, address, logRequests=0):
228 SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, address, logRequests=logRequests)
229
230 class BreakListenerThread(threading.Thread):
231 def __init__(self, host, port, queue):
232 threading.Thread.__init__(self)
233 self._host = host
234 self._port = int(port)
235 self._keepGoing = True
236 self._queue = queue
237 self._server = AGXMLRPCServer((self._host, self._port), logRequests=0)
238 self._server.register_function(self.update_breakpoints)
239 self._server.register_function(self.break_requested)
240 self._server.register_function(self.die)
241
242 def break_requested(self):
243 bn = BreakNotify(break_here=True)
244 self._queue.put(bn)
245 return ""
246
247 def update_breakpoints(self, pickled_Binary_bpts):
248 dict = pickle.loads(pickled_Binary_bpts.data)
249 bn = BreakNotify(bps=dict)
250 self._queue.put(bn)
251 return ""
252
253 def die(self):
254 bn = BreakNotify(kill=True)
255 self._queue.put(bn)
256 return ""
257
258 def run(self):
259 while self._keepGoing:
260 try:
261 self._server.handle_request()
262 except:
263 if _VERBOSE:
264 tp, val, tb = sys.exc_info()
265 print "Exception in BreakListenerThread.run():", str(tp), str(val)
266 self._keepGoing = False
267
268 def AskToStop(self):
269 self._keepGoing = False
270 if type(self._server) is not types.NoneType:
271 if _VERBOSE: print "Before calling server close on breakpoint server"
272 self._server.server_close()
273 if _VERBOSE: print "Calling server close on breakpoint server"
274 self._server = None
275
276
277 class DebuggerHarness(object):
278
279 def __init__(self):
280 # Host and port for debugger-side RPC server
281 self._hostname = sys.argv[1]
282 self._portNumber = int(sys.argv[2])
283 # Name the gui proxy object is registered under
284 self._breakPortNumber = int(sys.argv[3])
285 # Host and port where the gui proxy can be found.
286 self._guiHost = sys.argv[4]
287 self._guiPort = int(sys.argv[5])
288 # Command to debug.
289 self._command = sys.argv[6]
290 # Strip out the harness' arguments so that the process we run will see argv as if
291 # it was called directly.
292 sys.argv = sys.argv[6:]
293 self._currentFrame = None
294 self._wait = False
295 # Connect to the gui-side RPC server.
296 self._guiServerUrl = 'http://' + self._guiHost + ':' + str(self._guiPort) + '/'
297 if _VERBOSE: print "Connecting to gui server at ", self._guiServerUrl
298 self._guiServer = xmlrpclib.ServerProxy(self._guiServerUrl,allow_none=1)
299
300 # Start the break listener
301 self._breakQueue = Queue.Queue(50)
302 self._breakListener = BreakListenerThread(self._hostname, self._breakPortNumber, self._breakQueue)
303 self._breakListener.start()
304 # Create the debugger.
305 self._adb = Adb(self, self._breakQueue)
306
307 # Create the debugger-side RPC Server and register functions for remote calls.
308 self._server = AGXMLRPCServer((self._hostname, self._portNumber), logRequests=0)
309 self._server.register_function(self.set_step)
310 self._server.register_function(self.set_continue)
311 self._server.register_function(self.set_next)
312 self._server.register_function(self.set_return)
313 self._server.register_function(self.set_breakpoint)
314 self._server.register_function(self.clear_breakpoint)
315 self._server.register_function(self.set_all_breakpoints)
316 self._server.register_function(self.attempt_introspection)
317 self._server.register_function(self.execute_in_frame)
318 self._server.register_function(self.add_watch)
319 self._server.register_function(self.request_frame_document)
320
321 self.frame_stack = []
322 self.message_frame_dict = {}
323 self.introspection_list = []
324 atexit.register(self.do_exit)
325
326 def run(self):
327 self._adb.runFile(self._command)
328 self.do_exit(kill=True)
329
330
331 def do_exit(self, kill=False):
332 self._adb.set_quit()
333 self._breakListener.AskToStop()
334 self._server.server_close()
335 try:
336 self._guiServer.quit()
337 except:
338 pass
339 if kill:
340 try:
341 sys.exit()
342 except:
343 pass
344
345 def set_breakpoint(self, fileName, lineNo):
346 self._adb.set_break(fileName, lineNo)
347 return ""
348
349 def set_all_breakpoints(self, dict):
350 self._adb.clear_all_breaks()
351 for fileName in dict.keys():
352 lineList = dict[fileName]
353 for lineNumber in lineList:
354 self._adb.set_break(fileName, int(lineNumber))
355 if _VERBOSE: print "Setting break at ", str(lineNumber), " in file ", fileName
356 return ""
357
358 def clear_breakpoint(self, fileName, lineNo):
359 self._adb.clear_break(fileName, lineNo)
360 return ""
361
362 def add_watch(self, name, text, frame_message, run_once):
363 if len(frame_message) > 0:
364 frame = self.message_frame_dict[frame_message]
365 try:
366 item = eval(text, frame.f_globals, frame.f_locals)
367 return self.get_watch_document(item, name)
368 except:
369 tp, val, tb = sys.exc_info()
370 return self.get_exception_document(tp, val, tb)
371 return ""
372
373 def execute_in_frame(self, frame_message, command):
374 frame = self.message_frame_dict[frame_message]
375 output = cStringIO.StringIO()
376 out = sys.stdout
377 err = sys.stderr
378 sys.stdout = output
379 sys.stderr = output
380 try:
381 code = compile(command, '<string>', 'single')
382 exec code in frame.f_globals, frame.f_locals
383 return output.getvalue()
384 sys.stdout = out
385 sys.stderr = err
386 except:
387 sys.stdout = out
388 sys.stderr = err
389
390 tp, val, tb = sys.exc_info()
391 output = cStringIO.StringIO()
392 traceback.print_exception(tp, val, tb, file=output)
393 return output.getvalue()
394
395 def attempt_introspection(self, frame_message, chain):
396 try:
397 frame = self.message_frame_dict[frame_message]
398 if frame:
399 name = chain.pop(0)
400 if name == 'globals':
401 item = frame.f_globals
402 elif name == 'locals':
403 item = frame.f_locals
404
405 for name in chain:
406 item = self.getNextItem(item, name)
407 return self.get_introspection_document(item, name)
408 except:
409 tp, val, tb = sys.exc_info()
410 traceback.print_exception(tp, val, tb)
411 return self.get_empty_introspection_document()
412
413 def getNextItem(self, link, identifier):
414 tp = type(link)
415 if self.isTupleized(identifier):
416 return self.deTupleize(link, identifier)
417 else:
418 if tp == types.DictType or tp == types.DictProxyType:
419 return link[identifier]
420 else:
421 if hasattr(link, identifier):
422 return getattr(link, identifier)
423 if _VERBOSE or True: print "Failed to find link ", identifier, " on thing: ", self.saferepr(link), " of type ", repr(type(link))
424 return None
425
426 def isPrimitive(self, item):
427 tp = type(item)
428 return tp is types.IntType or tp is types.LongType or tp is types.FloatType \
429 or tp is types.BooleanType or tp is types.ComplexType \
430 or tp is types.StringType
431
432 def isTupleized(self, value):
433 return value.count('[')
434
435 def deTupleize(self, link, string1):
436 try:
437 start = string1.find('[')
438 end = string1.find(']')
439 num = int(string1[start+1:end])
440 return link[num]
441 except:
442 tp,val,tb = sys.exc_info()
443 if _VERBOSE: print "Got exception in deTupleize: ", val
444 return None
445
446 def wrapAndCompress(self, stringDoc):
447 import bz2
448 return xmlrpclib.Binary(bz2.compress(stringDoc))
449
450 def get_empty_introspection_document(self):
451 doc = getDOMImplementation().createDocument(None, "replacement", None)
452 return self.wrapAndCompress(doc.toxml())
453
454 def get_watch_document(self, item, identifier):
455 doc = getDOMImplementation().createDocument(None, "watch", None)
456 top_element = doc.documentElement
457 self.addAny(top_element, identifier, item, doc, 2)
458 return self.wrapAndCompress(doc.toxml())
459
460 def get_introspection_document(self, item, identifier):
461 doc = getDOMImplementation().createDocument(None, "replacement", None)
462 top_element = doc.documentElement
463 self.addAny(top_element, identifier, item, doc, 2)
464 return self.wrapAndCompress(doc.toxml())
465
466 def get_exception_document(self, name, tp, val, tb):
467 stack = traceback.format_exception(tp, val, tb)
468 wholeStack = ""
469 for line in stack:
470 wholeStack += line
471 doc = getDOMImplementation().createDocument(None, "watch", None)
472 top_element = doc.documentElement
473 item_node = doc.createElement("dict_nv_element")
474 item_node.setAttribute('value', wholeStack)
475 item_node.setAttribute('name', str(name))
476 top_element.appendChild(item_node)
477
478 cantIntro = [types.FunctionType,
479 types.LambdaType,
480 types.UnicodeType,
481 types.StringType,
482 types.NoneType,
483 types.IntType,
484 types.LongType,
485 types.FloatType,
486 types.BooleanType]
487
488 def addAny(self, top_element, name, item, doc, ply):
489 tp = type(item)
490
491 if tp in DebuggerHarness.cantIntro or ply < 1:
492 self.addNode(top_element,name, item, doc)
493 elif tp is types.TupleType or tp is types.ListType:
494 self.addTupleOrList(top_element, name, item, doc, ply - 1)
495 elif tp is types.DictType or tp is types.DictProxyType:
496 self.addDict(top_element, name, item, doc, ply -1)
497 elif inspect.ismodule(item):
498 self.addModule(top_element, name, item, doc, ply -1)
499 elif inspect.isclass(item) or tp is types.InstanceType:
500 self.addClass(top_element, name, item, doc, ply -1)
501 elif hasattr(item, '__dict__'):
502 self.addDictAttr(top_element, name, item, doc, ply -1)
503 else:
504 self.addNode(top_element,name, item, doc)
505
506
507 def canIntrospect(self, item):
508 tp = type(item)
509 if tp in DebuggerHarness.cantIntro:
510 return False
511 elif tp is types.TupleType or tp is types.ListType:
512 return len(item) > 0
513 elif tp is types.DictType or tp is types.DictProxyType:
514 return len(item) > 0
515 elif inspect.ismodule(item):
516 return True
517 elif inspect.isclass(item) or tp is types.InstanceType:
518 if hasattr(item, '__dict__'):
519 return True
520 elif hasattr(item, '__name__'):
521 return True
522 elif hasattr(item, '__module__'):
523 return True
524 elif hasattr(item, '__doc__'):
525 return True
526 else:
527 return False
528 elif hasattr(item, '__dict__'):
529 return len(item.__dict__) > 0
530 else:
531 return False
532
533 def addNode(self, parent_node, name, item, document):
534 item_node = document.createElement("dict_nv_element")
535 item_node.setAttribute('value', self.saferepr(item))
536 item_node.setAttribute('name', str(name))
537 introVal = str(self.canIntrospect(item))
538 item_node.setAttribute('intro', str(introVal))
539 parent_node.appendChild(item_node)
540
541
542 def addTupleOrList(self, top_node, name, tupple, doc, ply):
543 tupleNode = doc.createElement('tuple')
544 tupleNode.setAttribute('name', str(name))
545 tupleNode.setAttribute('value', self.saferepr(tupple))
546 top_node.appendChild(tupleNode)
547 count = 0
548 for item in tupple:
549 self.addAny(tupleNode, name +'[' + str(count) + ']',item, doc, ply -1)
550 count += 1
551
552 def addDictAttr(self, root_node, name, thing, document, ply):
553 dict_node = document.createElement('thing')
554 dict_node.setAttribute('name', name)
555 dict_node.setAttribute('value', self.saferepr(thing))
556 root_node.appendChild(dict_node)
557 self.addDict(dict_node, '', thing.__dict__, document, ply) # Not decreminting ply
558
559 def addDict(self, root_node, name, dict, document, ply):
560 if name != '':
561 dict_node = document.createElement('dict')
562 dict_node.setAttribute('name', name)
563 dict_node.setAttribute('value', self.saferepr(dict))
564 root_node.appendChild(dict_node)
565 else:
566 dict_node = root_node
567 for key in dict.keys():
568 strkey = str(key)
569 try:
570 value = dict[key]
571 self.addAny(dict_node, strkey, value, document, ply-1)
572 except:
573 if _VERBOSE:
574 tp,val,tb=sys.exc_info()
575 print "Error recovering key: ", str(key), " from node ", str(name), " Val = ", str(val)
576 traceback.print_exception(tp, val, tb)
577
578 def addClass(self, root_node, name, class_item, document, ply):
579 item_node = document.createElement('class')
580 item_node.setAttribute('name', str(name))
581 item_node.setAttribute('value', self.saferepr(class_item))
582 root_node.appendChild(item_node)
583 try:
584 if hasattr(class_item, '__dict__'):
585 self.addDict(item_node, '', class_item.__dict__, document, ply -1)
586 except:
587 tp,val,tb=sys.exc_info()
588 if _VERBOSE:
589 traceback.print_exception(tp, val, tb)
590 try:
591 if hasattr(class_item, '__name__'):
592 self.addAny(item_node,'__name__',class_item.__name__, document, ply -1)
593 except:
594 tp,val,tb=sys.exc_info()
595 if _VERBOSE:
596 traceback.print_exception(tp, val, tb)
597 try:
598 if hasattr(class_item, '__module__'):
599 self.addAny(item_node, '__module__', class_item.__module__, document, ply -1)
600 except:
601 tp,val,tb=sys.exc_info()
602 if _VERBOSE:
603 traceback.print_exception(tp, val, tb)
604 try:
605 if hasattr(class_item, '__doc__'):
606 self.addAny(item_node, '__doc__', class_item.__doc__, document, ply -1)
607 except:
608 tp,val,tb=sys.exc_info()
609 if _VERBOSE:
610 traceback.print_exception(tp, val, tb)
611 try:
612 if hasattr(class_item, '__bases__'):
613 self.addAny(item_node, '__bases__', class_item.__bases__, document, ply -1)
614 except:
615 tp,val,tb=sys.exc_info()
616 if _VERBOSE:
617 traceback.print_exception(tp, val, tb)
618
619 def addModule(self, root_node, name, module_item, document, ply):
620 item_node = document.createElement('module')
621 item_node.setAttribute('name', str(name))
622 item_node.setAttribute('value', self.saferepr(module_item))
623 root_node.appendChild(item_node)
624 try:
625 if hasattr(module_item, '__file__'):
626 self.addAny(item_node, '__file__', module_item.__file__, document, ply -1)
627 except:
628 pass
629 try:
630 if hasattr(module_item, '__doc__'):
631 self.addAny(item_node,'__doc__', module_item.__doc__, document, ply -1)
632 except:
633 pass
634
635
636
637 def getFrameXML(self, base_frame):
638
639 self.frame_stack = []
640 frame = base_frame
641 while frame is not None:
642 if((frame.f_code.co_filename.count('DebuggerHarness.py') == 0) or _DEBUG_DEBUGGER):
643 self.frame_stack.append(frame)
644 frame = frame.f_back
645 self.frame_stack.reverse()
646 self.message_frame_dict = {}
647 doc = getDOMImplementation().createDocument(None, "stack", None)
648 top_element = doc.documentElement
649 numberFrames = len(self.frame_stack)
650 for index in range(numberFrames):
651 frame = self.frame_stack[index]
652 message = self._adb.frame2message(frame)
653 # We include globals and locals only for the last frame as an optimization for cases
654 # where there are a lot of frames.
655 self.addFrame(frame, top_element, doc, includeContent=(index == numberFrames - 1))
656 return doc.toxml()
657
658 def addFrame(self, frame, root_element, document, includeContent=False):
659 frameNode = document.createElement('frame')
660 root_element.appendChild(frameNode)
661
662 code = frame.f_code
663 filename = code.co_filename
664 frameNode.setAttribute('file', str(filename))
665 frameNode.setAttribute('line', str(frame.f_lineno))
666 message = self._adb.frame2message(frame)
667 frameNode.setAttribute('message', message)
668 self.message_frame_dict[message] = frame
669 if includeContent:
670 self.addDict(frameNode, "locals", frame.f_locals, document, 2)
671 self.addNode(frameNode, "globals", frame.f_globals, document)
672
673 def request_frame_document(self, message):
674 frame = self.message_frame_dict[message]
675 doc = getDOMImplementation().createDocument(None, "stack", None)
676 top_element = doc.documentElement
677 if frame:
678 self.addFrame(frame, top_element, doc, includeContent=True)
679 return xmlrpclib.Binary(bz2.compress(doc.toxml()))
680
681 def getRepr(self, varName, globals, locals):
682 try:
683 return repr(eval(varName, globals, locals))
684 except:
685 return 'Error: Could not recover value.'
686
687
688 def saferepr(self, thing):
689 try:
690 try:
691 return repr(thing)
692 except:
693 return str(type(thing))
694 except:
695 tp, val, tb = sys.exc_info()
696 #traceback.print_exception(tp, val, tb)
697 return repr(val)
698
699 # The debugger calls this method when it reaches a breakpoint.
700 def interaction(self, message, frame, info):
701 if _VERBOSE:
702 print 'hit debug side interaction'
703 self._adb._userBreak = False
704
705 self._currentFrame = frame
706 done = False
707 while not done:
708 try:
709 xml = self.getFrameXML(frame)
710 arg = xmlrpclib.Binary(bz2.compress(xml))
711 if _VERBOSE:
712 print '============== calling gui side interaction============'
713 self._guiServer.interaction(xmlrpclib.Binary(message), arg, info)
714 if _VERBOSE:
715 print 'after interaction'
716 done = True
717 except:
718 tp, val, tb = sys.exc_info()
719 if True or _VERBOSE:
720 print 'Error contacting GUI server!: '
721 try:
722 traceback.print_exception(tp, val, tb)
723 except:
724 print "Exception printing traceback",
725 tp, val, tb = sys.exc_info()
726 traceback.print_exception(tp, val, tb)
727 done = False
728 # Block while waiting to be called back from the GUI. Eventually, self._wait will
729 # be set false by a function on this side. Seems pretty lame--I'm surprised it works.
730 self.waitForRPC()
731
732
733 def waitForRPC(self):
734 self._wait = True
735 while self._wait :
736 try:
737 if _VERBOSE:
738 print "+++ in harness wait for rpc, before handle_request"
739 self._server.handle_request()
740 if _VERBOSE:
741 print "+++ in harness wait for rpc, after handle_request"
742 except:
743 if _VERBOSE:
744 tp, val, tb = sys.exc_info()
745 print "Got waitForRpc exception : ", repr(tp), ": ", val
746 #time.sleep(0.1)
747
748 def set_step(self):
749 self._adb.set_step()
750 self._wait = False
751 return ""
752
753 def set_continue(self):
754 self._adb.set_continue()
755 self._wait = False
756 return ""
757
758 def set_next(self):
759 self._adb.set_next(self._currentFrame)
760 self._wait = False
761 return ""
762
763 def set_return(self):
764 self._adb.set_return(self._currentFrame)
765 self._wait = False
766 return ""
767
768 if __name__ == '__main__':
769 try:
770 harness = DebuggerHarness()
771 harness.run()
772 harness.do_exit(kill=True)
773 except SystemExit:
774 print "Exiting..."
775 except:
776 tp, val, tb = sys.exc_info()
777 traceback.print_exception(tp, val, tb)