]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/ide/activegrid/tool/DebuggerHarness.py
   1 #---------------------------------------------------------------------------- 
   2 # Name:         DebuggerHarness.py 
   9 # Copyright:    (c) 2005 ActiveGrid, Inc. 
  10 # License:      wxWindows License 
  11 #---------------------------------------------------------------------------- 
  14 import SimpleXMLRPCServer
 
  22 from xml
.dom
.minidom 
import getDOMImplementation
 
  28 if sys
.platform
.startswith("win"): 
  35 _DEBUG_DEBUGGER 
= False 
  39     def __init__(self
, harness
, queue
): 
  40         bdb
.Bdb
.__init
__(self
) 
  41         self
._harness 
= harness
 
  42         self
._userBreak 
= False 
  44         self
._knownCantExpandFiles 
= {}  
  45         self
._knownExpandedFiles 
= {}  
  47     def getLongName(self
, filename
): 
  50         if self
._knownCantExpandFiles
.get(filename
): 
  52         if self
._knownExpandedFiles
.get(filename
): 
  53             return self
._knownExpandedFiles
.get(filename
) 
  55             newname 
= win32api
.GetLongPathName(filename
) 
  56             self
._knownExpandedFiles
[filename
] = newname
 
  59             self
._knownCantExpandFiles
[filename
] = filename
 
  62     def canonic(self
, orig_filename
): 
  63         if orig_filename 
== "<" + orig_filename
[1:-1] + ">": 
  65         filename 
= self
.getLongName(orig_filename
)     
  67         canonic 
= self
.fncache
.get(filename
) 
  69             canonic 
= os
.path
.abspath(filename
) 
  70             canonic 
= os
.path
.normcase(canonic
) 
  71             self
.fncache
[filename
] = canonic
 
  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 
  81     def do_clear(self
, arg
): 
  82         bdb
.Breakpoint
.bpbynumber
[int(arg
)].deleteMe() 
  84     def user_line(self
, frame
): 
  85         if self
.in_debugger_code(frame
): 
  88         message 
= self
.__frame
2message
(frame
) 
  89         self
._harness
.interaction(message
, frame
, "") 
  91     def user_call(self
, frame
, argument_list
): 
  92         if self
.in_debugger_code(frame
): 
  95         if self
.stop_here(frame
): 
  96             message 
= self
.__frame
2message
(frame
) 
  97             self
._harness
.interaction(message
, frame
, "") 
  99     def user_return(self
, frame
, return_value
): 
 100         if self
.in_debugger_code(frame
): 
 103         message 
= self
.__frame
2message
(frame
) 
 104         self
._harness
.interaction(message
, frame
, "") 
 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
 
 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
) 
 116     def in_debugger_code(self
, frame
): 
 117         if _DEBUG_DEBUGGER
: return False 
 118         message 
= self
.__frame
2message
(frame
) 
 119         return message
.count('DebuggerHarness') > 0 
 121     def frame2message(self
, frame
): 
 122         return self
.__frame
2message
(frame
) 
 124     def __frame2message(self
, frame
): 
 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
) 
 134     def runFile(self
, fileName
): 
 137         #global_dict['__name__'] = '__main__' 
 139             fileToRun 
= open(fileName
, mode
='r') 
 140             if _VERBOSE
: print "Running file ", fileName
 
 141             sys
.settrace(self
.trace_dispatch
) 
 143             exec fileToRun 
in __main__
.__dict
__,__main__
.__dict
__ 
 147             tp
, val
, tb 
= sys
.exc_info() 
 148             traceback
.print_exception(tp
, val
, tb
) 
 154     def trace_dispatch(self
, frame
, event
, arg
): 
 157         # Check for ui events 
 160             return self
.dispatch_line(frame
) 
 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
 
 171         while self
._queue
.qsize(): 
 173                 item 
= self
._queue
.get_nowait() 
 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()) 
 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
: 
 189                 if _VERBOSE
: print "Setting break at line ", str(lineNumber
), " in file ", self
.canonic(fileName
) 
 190                 self
.set_break(fileName
, int(lineNumber
)) 
 193     def stop_here(self
, frame
): 
 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
: 
 202         while frame 
is not None and frame 
is not self
.stopframe
: 
 203             if frame 
is self
.botframe
: 
 208 class BreakNotify(object): 
 209     def __init__(self
, bps
=None, break_here
=False, kill
=False): 
 211         self
._break
_here 
= break_here
 
 215         return self
._break
_here
 
 220     def getBreakpoints(self
): 
 223     def hasBreakpoints(self
): 
 224         return (self
._bps 
!= None) 
 226 class AGXMLRPCServer(SimpleXMLRPCServer
.SimpleXMLRPCServer
): 
 227     def __init__(self
, address
, logRequests
=0): 
 228         SimpleXMLRPCServer
.SimpleXMLRPCServer
.__init
__(self
, address
, logRequests
=logRequests
)                
 230 class BreakListenerThread(threading
.Thread
): 
 231     def __init__(self
, host
, port
, queue
): 
 232         threading
.Thread
.__init
__(self
) 
 234         self
._port 
= int(port
) 
 235         self
._keepGoing 
= True 
 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
) 
 242     def break_requested(self
): 
 243         bn 
= BreakNotify(break_here
=True) 
 247     def update_breakpoints(self
, pickled_Binary_bpts
): 
 248         dict = pickle
.loads(pickled_Binary_bpts
.data
) 
 249         bn 
= BreakNotify(bps
=dict) 
 254         bn 
= BreakNotify(kill
=True) 
 259         while self
._keepGoing
: 
 261                 self
._server
.handle_request()  
 264                     tp
, val
, tb 
= sys
.exc_info() 
 265                     print "Exception in BreakListenerThread.run():", str(tp
), str(val
) 
 266                 self
._keepGoing 
= False 
 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" 
 277 class DebuggerHarness(object): 
 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]) 
 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 
 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) 
 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
) 
 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
) 
 321         self
.frame_stack 
= [] 
 322         self
.message_frame_dict 
= {} 
 323         self
.introspection_list 
= [] 
 324         atexit
.register(self
.do_exit
) 
 327         self
._adb
.runFile(self
._command
) 
 328         self
.do_exit(kill
=True) 
 331     def do_exit(self
, kill
=False): 
 333         self
._breakListener
.AskToStop() 
 334         self
._server
.server_close() 
 336             self
._guiServer
.quit() 
 345     def set_breakpoint(self
, fileName
, lineNo
): 
 346         self
._adb
.set_break(fileName
, lineNo
) 
 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
 
 358     def clear_breakpoint(self
, fileName
, lineNo
): 
 359         self
._adb
.clear_break(fileName
, lineNo
) 
 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
]  
 366                 item 
= eval(text
, frame
.f_globals
, frame
.f_locals
) 
 367                 return self
.get_watch_document(item
, name
) 
 369                 tp
, val
, tb 
= sys
.exc_info() 
 370                 return self
.get_exception_document(tp
, val
, tb
)  
 373     def execute_in_frame(self
, frame_message
, command
): 
 374         frame 
= self
.message_frame_dict
[frame_message
] 
 375         output 
= cStringIO
.StringIO() 
 381             code 
= compile(command
, '<string>', 'single') 
 382             exec code 
in frame
.f_globals
, frame
.f_locals
 
 383             return output
.getvalue() 
 390             tp
, val
, tb 
= sys
.exc_info()            
 391             output 
= cStringIO
.StringIO() 
 392             traceback
.print_exception(tp
, val
, tb
, file=output
) 
 393             return output
.getvalue()    
 395     def attempt_introspection(self
, frame_message
, chain
): 
 397             frame 
= self
.message_frame_dict
[frame_message
] 
 400                 if name 
== 'globals': 
 401                     item 
= frame
.f_globals
 
 402                 elif name 
== 'locals': 
 403                     item 
= frame
.f_locals
 
 406                     item 
= self
.getNextItem(item
, name
) 
 407                 return self
.get_introspection_document(item
, name
) 
 409             tp
, val
, tb 
= sys
.exc_info() 
 410             traceback
.print_exception(tp
, val
, tb
) 
 411         return self
.get_empty_introspection_document()    
 413     def getNextItem(self
, link
, identifier
): 
 415         if self
.isTupleized(identifier
): 
 416             return self
.deTupleize(link
, identifier
) 
 418             if tp 
== types
.DictType 
or tp 
== types
.DictProxyType
: 
 419                 return link
[identifier
] 
 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
)) 
 426     def isPrimitive(self
, 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  
 
 432     def isTupleized(self
, value
): 
 433         return value
.count('[') 
 435     def deTupleize(self
, link
, string1
): 
 437             start 
= string1
.find('[') 
 438             end 
= string1
.find(']') 
 439             num 
= int(string1
[start
+1:end
]) 
 442             tp
,val
,tb 
= sys
.exc_info() 
 443             if _VERBOSE
: print "Got exception in deTupleize: ", val
 
 446     def wrapAndCompress(self
, stringDoc
): 
 448         return xmlrpclib
.Binary(bz2
.compress(stringDoc
)) 
 450     def get_empty_introspection_document(self
): 
 451         doc 
= getDOMImplementation().createDocument(None, "replacement", None) 
 452         return self
.wrapAndCompress(doc
.toxml()) 
 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()) 
 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()) 
 466     def get_exception_document(self
, name
, tp
, val
, tb
):                   
 467         stack 
= traceback
.format_exception(tp
, val
, tb
) 
 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
) 
 478     cantIntro 
= [types
.FunctionType
,  
 488     def addAny(self
, top_element
, name
, item
, doc
, ply
): 
 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) 
 504             self
.addNode(top_element
,name
, item
, doc
)  
 507     def canIntrospect(self
, item
): 
 509         if tp 
in DebuggerHarness
.cantIntro
: 
 511         elif tp 
is types
.TupleType 
or tp 
is types
.ListType
: 
 513         elif tp 
is types
.DictType 
or tp 
is types
.DictProxyType
:  
 515         elif inspect
.ismodule(item
):  
 517         elif inspect
.isclass(item
) or tp 
is types
.InstanceType
: 
 518             if hasattr(item
, '__dict__'): 
 520             elif hasattr(item
, '__name__'): 
 522             elif hasattr(item
, '__module__'): 
 524             elif hasattr(item
, '__doc__'): 
 528         elif hasattr(item
, '__dict__'): 
 529             return len(item
.__dict
__) > 0 
 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
) 
 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
) 
 549             self
.addAny(tupleNode
, name 
+'[' + str(count
) + ']',item
, doc
, ply 
-1) 
 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 
 559     def addDict(self
, root_node
, name
, dict, document
, ply
): 
 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
) 
 566             dict_node 
= root_node
 
 567         for key 
in dict.keys(): 
 571                 self
.addAny(dict_node
, strkey
, value
, document
, ply
-1) 
 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
) 
 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
) 
 584              if hasattr(class_item
, '__dict__'): 
 585                 self
.addDict(item_node
, '', class_item
.__dict
__, document
, ply 
-1) 
 587              tp
,val
,tb
=sys
.exc_info() 
 589                 traceback
.print_exception(tp
, val
, tb
) 
 591              if hasattr(class_item
, '__name__'): 
 592                 self
.addAny(item_node
,'__name__',class_item
.__name
__, document
, ply 
-1) 
 594              tp
,val
,tb
=sys
.exc_info() 
 596                 traceback
.print_exception(tp
, val
, tb
) 
 598              if hasattr(class_item
, '__module__'): 
 599                 self
.addAny(item_node
, '__module__', class_item
.__module
__, document
, ply 
-1) 
 601              tp
,val
,tb
=sys
.exc_info() 
 603                 traceback
.print_exception(tp
, val
, tb
) 
 605              if hasattr(class_item
, '__doc__'): 
 606                 self
.addAny(item_node
, '__doc__', class_item
.__doc
__, document
, ply 
-1) 
 608              tp
,val
,tb
=sys
.exc_info() 
 610                 traceback
.print_exception(tp
, val
, tb
) 
 612              if hasattr(class_item
, '__bases__'): 
 613                 self
.addAny(item_node
, '__bases__', class_item
.__bases
__, document
, ply 
-1) 
 615              tp
,val
,tb
=sys
.exc_info() 
 617                 traceback
.print_exception(tp
, val
, tb
) 
 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
) 
 625              if hasattr(module_item
, '__file__'): 
 626                 self
.addAny(item_node
, '__file__', module_item
.__file
__, document
, ply 
-1) 
 630              if hasattr(module_item
, '__doc__'): 
 631                 self
.addAny(item_node
,'__doc__', module_item
.__doc
__, document
, ply 
-1) 
 637     def getFrameXML(self
, base_frame
): 
 639         self
.frame_stack 
= [] 
 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
) 
 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)) 
 658     def addFrame(self
, frame
, root_element
, document
, includeContent
=False): 
 659         frameNode 
= document
.createElement('frame') 
 660         root_element
.appendChild(frameNode
) 
 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
 
 670             self
.addDict(frameNode
, "locals", frame
.f_locals
, document
, 2)         
 671             self
.addNode(frameNode
, "globals", frame
.f_globals
,  document
) 
 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
 
 678             self
.addFrame(frame
, top_element
, doc
, includeContent
=True) 
 679         return xmlrpclib
.Binary(bz2
.compress(doc
.toxml())) 
 681     def getRepr(self
, varName
, globals, locals): 
 683             return repr(eval(varName
, globals, locals)) 
 685             return 'Error: Could not recover value.' 
 688     def saferepr(self
, thing
): 
 693                 return str(type(thing
)) 
 695             tp
, val
, tb 
= sys
.exc_info() 
 696             #traceback.print_exception(tp, val, tb) 
 699     # The debugger calls this method when it reaches a breakpoint. 
 700     def interaction(self
, message
, frame
, info
): 
 702             print 'hit debug side interaction' 
 703         self
._adb
._userBreak 
= False 
 705         self
._currentFrame 
= frame
 
 709                 xml 
= self
.getFrameXML(frame
) 
 710                 arg 
= xmlrpclib
.Binary(bz2
.compress(xml
)) 
 712                     print '============== calling gui side interaction============' 
 713                 self
._guiServer
.interaction(xmlrpclib
.Binary(message
), arg
, info
) 
 715                     print 'after interaction' 
 718                 tp
, val
, tb 
= sys
.exc_info() 
 720                     print 'Error contacting GUI server!: ' 
 722                         traceback
.print_exception(tp
, val
, tb
) 
 724                         print "Exception printing traceback",  
 725                         tp
, val
, tb 
= sys
.exc_info() 
 726                         traceback
.print_exception(tp
, val
, tb
) 
 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. 
 733     def waitForRPC(self
): 
 738                     print "+++ in harness wait for rpc, before handle_request" 
 739                 self
._server
.handle_request() 
 741                     print "+++ in harness wait for rpc, after handle_request" 
 744                     tp
, val
, tb 
= sys
.exc_info() 
 745                     print "Got waitForRpc exception : ", repr(tp
), ": ", val
 
 753     def set_continue(self
): 
 754         self
._adb
.set_continue() 
 759         self
._adb
.set_next(self
._currentFrame
) 
 763     def set_return(self
): 
 764         self
._adb
.set_return(self
._currentFrame
) 
 768 if __name__ 
== '__main__': 
 770         harness 
= DebuggerHarness() 
 772         harness
.do_exit(kill
=True) 
 776         tp
, val
, tb 
= sys
.exc_info() 
 777         traceback
.print_exception(tp
, val
, tb
)