def _HandleBreakPoint(self, frame, tb, reason): traceenter("Calling HandleBreakPoint with reason", reason,"at frame", _dumpf(frame)) traceenter(" Current frame is", _dumpf(self.currentframe)) try: resumeAction = self.debugApplication.HandleBreakPoint(reason) tracev("HandleBreakPoint returned with ", resumeAction) except pythoncom.com_error as details: # Eeek - the debugger is dead, or something serious is happening. # Assume we should continue resumeAction = axdebug.BREAKRESUMEACTION_CONTINUE trace("HandleBreakPoint FAILED with", details) self.stack = [] self.curindex = 0 if resumeAction == axdebug.BREAKRESUMEACTION_ABORT: self.set_quit() elif resumeAction == axdebug.BREAKRESUMEACTION_CONTINUE: tracev("resume action is continue") self.set_continue() elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_INTO: tracev("resume action is step") self.set_step() elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_OVER: tracev("resume action is next") self.set_next(frame) elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_OUT: tracev("resume action is stop out") self.set_return(frame) else: raise ValueError("unknown resume action flags") self.breakReason = None
def SetupAXDebugging(self, baseFrame = None, userFrame = None): """Get ready for potential debugging. Must be called on the thread that is being debugged. """ # userFrame is for non AXScript debugging. This is the first frame of the # users code. if userFrame is None: userFrame = baseFrame else: # We have missed the "dispatch_call" function, so set this up now! userFrame.f_locals['__axstack_address__'] = axdebug.GetStackAddress() traceenter("SetupAXDebugging", self) self._threadprotectlock.acquire() try: thisThread = win32api.GetCurrentThreadId() if self.debuggingThread is None: self.debuggingThread = thisThread else: if self.debuggingThread!=thisThread: trace("SetupAXDebugging called on other thread - ignored!") return # push our context. self.recursiveData.insert(0, (self.logicalbotframe,self.stopframe, self.currentframe,self.debuggingThreadStateHandle)) finally: self._threadprotectlock.release() trace("SetupAXDebugging has base frame as", _dumpf(baseFrame)) self.botframe = baseFrame self.stopframe = userFrame self.logicalbotframe = baseFrame self.currentframe = None self.debuggingThreadStateHandle = axdebug.GetThreadStateHandle() self._BreakFlagsChanged()
def GetPathName( self ): # Result must be (string, int) where the int is a BOOL # - TRUE if the path refers to the original file for the document. # - FALSE if the path refers to a newly created temporary file. # - raise Exception(scode=E_FAIL) if no source file can be created/determined. trace("GetPathName") try: return win32api.GetFullPathName(self.module.__file__), 1 except (AttributeError, win32api.error): raise Exception(scode==E_FAIL)
def _HandleBreakPoint(self, frame, tb, reason): traceenter("Calling HandleBreakPoint with reason", reason,"at frame", _dumpf(frame)) traceenter(" Current frame is", _dumpf(self.currentframe)) try: resumeAction = self.debugApplication.HandleBreakPoint(reason) tracev("HandleBreakPoint returned with ", resumeAction) except pythoncom.com_error, details: # Eeek - the debugger is dead, or something serious is happening. # Assume we should continue resumeAction = axdebug.BREAKRESUMEACTION_CONTINUE trace("HandleBreakPoint FAILED with", details)
def GetDeferredText(self, dwTextStartCookie, maxChars, bWantAttr): try: trace("GetDeferredText", dwTextStartCookie, maxChars, bWantAttr) cont = self._GetCodeContainer() if bWantAttr: attr = cont.GetSyntaxColorAttributes() else: attr = None return cont.text, attr except: traceback.print_exc()
def _OnSetBreakPoint(self, key, codeContext, bps, lineNo): traceenter("_OnSetBreakPoint", self, key, codeContext, bps, lineNo) if bps==axdebug.BREAKPOINT_ENABLED: problem = self.set_break(key, lineNo) if problem: print("*** set_break failed -", problem) trace("_OnSetBreakPoint just set BP and has breaks", self.breaks) else: self.clear_break(key, lineNo) self._BreakFlagsChanged() trace("_OnSetBreakPoint leaving with breaks", self.breaks)
def dispatch_call(self, frame, arg): traceenter("dispatch_call",_dumpf(frame)) frame.f_locals['__axstack_address__'] = axdebug.GetStackAddress() if frame is self.botframe: trace("dispatch_call is self.botframe - returning tracer") return self.trace_dispatch # Not our bottom frame. If we have a document for it, # then trace it, otherwise run at full speed. if self.codeContainerProvider.FromFileName(frame.f_code.co_filename) is None: trace("dispatch_call has no document for", _dumpf(frame), "- skipping trace!") ## sys.settrace(None) return None return self.trace_dispatch
def ResetAXDebugging(self): traceenter("ResetAXDebugging", self, "with refcount", len(self.recursiveData)) if win32api.GetCurrentThreadId()!=self.debuggingThread: trace("ResetAXDebugging called on other thread") return if len(self.recursiveData)==0: # print "ResetAXDebugging called for final time." self.logicalbotframe = None self.debuggingThread = None self.currentframe = None self.debuggingThreadStateHandle = None return self.logbotframe, self.stopframe, self.currentframe, self.debuggingThreadStateHandle = self.recursiveData[0] self.recursiveData = self.recursiveData[1:]
def dispatch_line(self, frame): traceenter("dispatch_line", _dumpf(frame), _dumpf(self.botframe)) # trace("logbotframe is", _dumpf(self.logicalbotframe), "botframe is", self.botframe) if frame is self.logicalbotframe: trace("dispatch_line", _dumpf(frame), "for bottom frame returing tracer") # The next code executed in the frame above may be a builtin (eg, apply()) # in which sys.trace needs to be set. sys.settrace(self.trace_dispatch) # And return the tracer incase we are about to execute Python code, # in which case sys tracer is ignored! return self.trace_dispatch if self.codeContainerProvider.FromFileName(frame.f_code.co_filename) is None: trace("dispatch_line has no document for", _dumpf(frame), "- skipping trace!") return None self.currentframe = frame # So the stack sniffer knows our most recent, debuggable code. return bdb.Bdb.dispatch_line(self, frame)
def _BreakFlagsChanged(self): traceenter("_BreakFlagsChanged to %s with our thread = %s, and debugging thread = %s" % (self.breakFlags, self.debuggingThread, win32api.GetCurrentThreadId())) trace("_BreakFlagsChanged has breaks", self.breaks) # If a request comes on our debugging thread, then do it now! # if self.debuggingThread!=win32api.GetCurrentThreadId(): # return if len(self.breaks) or self.breakFlags: if self.logicalbotframe: trace("BreakFlagsChange with bot frame", _dumpf(self.logicalbotframe)) # We have frames not to be debugged (eg, Scripting engine frames # (sys.settrace will be set when out logicalbotframe is hit - # this may not be the right thing to do, as it may not cause the # immediate break we desire.) self.logicalbotframe.f_trace = self.trace_dispatch else: trace("BreakFlagsChanged, but no bottom frame") if self.stopframe is not None: self.stopframe.f_trace = self.trace_dispatch # If we have the thread-state for the thread being debugged, then # we dynamically set its trace function - it is possible that the thread # being debugged is in a blocked call (eg, a message box) and we # want to hit the debugger the instant we return if self.debuggingThreadStateHandle is not None and \ self.breakFlags and \ self.debuggingThread != win32api.GetCurrentThreadId(): axdebug.SetThreadStateTrace(self.debuggingThreadStateHandle, self.trace_dispatch)
def CloseApp(self): traceenter("ClosingApp") self.reset() self.logicalbotframe = None if self.stackSnifferCookie is not None: try: self.debugApplication.RemoveStackFrameSniffer(self.stackSnifferCookie) except pythoncom.com_error: trace("*** Could not RemoveStackFrameSniffer %d" % (self.stackSnifferCookie)) if self.stackSniffer: _wrap_remove(self.stackSniffer) self.stackSnifferCookie = self.stackSniffer = None if self.appEventConnection is not None: self.appEventConnection.Disconnect() self.appEventConnection = None self.debugApplication = None self.appDebugger = None if self.codeContainerProvider is not None: self.codeContainerProvider.Close() self.codeContainerProvider = None
def SetupAXDebugging(self, baseFrame=None, userFrame=None): """Get ready for potential debugging. Must be called on the thread that is being debugged. """ # userFrame is for non AXScript debugging. This is the first frame of the # users code. if userFrame is None: userFrame = baseFrame else: # We have missed the "dispatch_call" function, so set this up now! userFrame.f_locals[ '__axstack_address__'] = axdebug.GetStackAddress() traceenter("SetupAXDebugging", self) self._threadprotectlock.acquire() try: thisThread = win32api.GetCurrentThreadId() if self.debuggingThread is None: self.debuggingThread = thisThread else: if self.debuggingThread != thisThread: trace("SetupAXDebugging called on other thread - ignored!") return # push our context. self.recursiveData.insert( 0, (self.logicalbotframe, self.stopframe, self.currentframe, self.debuggingThreadStateHandle)) finally: self._threadprotectlock.release() trace("SetupAXDebugging has base frame as", _dumpf(baseFrame)) self.botframe = baseFrame self.stopframe = userFrame self.logicalbotframe = baseFrame self.currentframe = None self.debuggingThreadStateHandle = axdebug.GetThreadStateHandle() self._BreakFlagsChanged()
def OnCreateDocumentContext(self): # Result must be a PyIUnknown trace("OnCreateDocumentContext") raise Exception(scode=winerror.E_NOTIMPL)
def GetScriptTextAttributes(self, codeText, delimterText, flags): # Result must be an attribute sequence of same "length" as the code. trace("GetScriptTextAttributes", delimterText, flags) raise Exception(scode=winerror.E_NOTIMPL)
def OnCreateDocumentContext( self ): # Result must be a PyIUnknown trace("OnCreateDocumentContext") raise Exception(scode=winerror.E_NOTIMPL)
def GetFileName(self): # Result is a string with just the name of the document, no path information. trace("GetFileName") return os.path.split(module.__file__)
def NotifyChanged(): trace("NotifyChanged") raise Exception(scode=winerror.E_NOTIMPL)
def trace_dispatch(self, frame, event, arg): traceenter("trace_dispatch", _dumpf(frame), event, arg) if self.debugApplication is None: trace("trace_dispatch has no application!") return # None return bdb.Bdb.trace_dispatch(self, frame, event, arg)
def _query_interface_(self, iid): from win32com.util import IIDToInterfaceName trace("PySourceModuleDebugDocumentHost QI with %s (%s)" % (IIDToInterfaceName(iid), str(iid))) return 0
def GetFileName(self): # Result is a string with just the name of the document, no path # information. trace("GetFileName") return os.path.split(module.__file__)