[pywin32-bugs] [ pywin32-Bugs-1119799 ] Active Debugging bugs
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: SourceForge.net <no...@so...> - 2005-02-10 03:35:09
|
Bugs item #1119799, was opened at 2005-02-10 03:35 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=551954&aid=1119799&group_id=78018 Category: com Group: None Status: Open Resolution: None Priority: 5 Submitted By: Kiriakos Vlahos (kvlahos) Assigned to: Nobody/Anonymous (nobody) Summary: Active Debugging bugs Initial Comment: I know that Active Scripting is a bit passe, but I have written a "Smart" Active Scripting host that works well with VBScript and JScript and I thought that it would cool if it worked with Python. It did not work out of the box. I played a bit with PythonWin and I have made it work after introducing various changes. Below I discribed the resolved and outstanding issues. (pywin32 build 203) a) ActiveScriptDebug fails when queried for IActiveScript The class ActiveScriptDebug in debug.py implements the IActiveScriptDebug interface. Hosts get access to this interface by quering the IActiveScript interface. According to the MS specification the IActiveScriptDebug should provide back the IActiveScript inteface when queried for it. Indeed this happens when the host calls GetScriptBlockInfo on IDebugDocumentHelper when handling breakpoints and the like (and in a couple of other cases). When this happens ActiveScript debug does not return a valid Interface and the Process Debug Manager (PDM) raises an exception preventing debugging. A workaround is to modify following method: def _query_interface_(self, iid): trace("DebuggerQI with", iid) return _wrap(self.debugMgr.scriptEngine, iid) Of course the Interface returned is not the same as the original IActiveScript and the host should discard it. But it keeps PDM happy. I could find no way to retrieve the original interface. Any ideas? b) Adb.OnDisconnect debugger This method should set the appDebugger to None. Checking the existance of appDebugger provides a good way to see whether debugging should take palce or not. (see next issue). There is no reason to slow down code if an appDebugger does not exist. Modified method: def OnDisconnectDebugger(self): traceenter("OnDisconnectDebugger") self.appDebugger = None #KV self.set_quit() c) Debugger tracing never starts If I understand it well, debugging is supposed to start after a call to OnEnterScript. This method finds the right stackframe, passes it to adb.SetupAXDebugging which calls _BreakFlagsChanged. This last method sets the frame.f_trace to trace_dispatch. However, just setting f_trace is not enough to start debugger tracing. sys.settrace needs to be called somewhere, or else the running of the code should be done through the run, runexec, runevall etc. methods of the debugger. This second method is much better I think (avoids fiddling with the frames directly and traces only the script code), but I have implemented the first method by modifying : def OnEnterScript(self): trace("OnEnterScript") baseFrame = sys._getframe().f_back self.adb.SetupAXDebugging(baseFrame) if self.adb.appDebugger: sys.settrace(self.adb.trace_dispatch) d) Debugger tracing never stops (after the above change) Debugging is supposed to stop when the adb.OnDisconnectDebugger is called since this calls the set_quit method which in turn calls sys.settrace(None). However, OnDisconnectDebugger is called on a different thread from the Script thread (not 100% sure on this) and the effect is that the Script thread (and PyWin) carries on beign traced by the debugger. I have modified: def OnLeaveScript(self): trace("OnLeaveScript") self.adb.ResetAXDebugging() sys.settrace(None); # KV Implementing the second solution described above would be simpler and cleaner than this though. e) Code positions are reported incorrectly With the above changes I could set and handle breakpoints examine the stack frames and get access to the local variables just fine. One problem though was that the posisitions of the breakpoints and errors returned by PyWin were incorrect. This is due to the fact that when the Engine receives code from the hosts it removes the CRs using RemoveCR in framework.py. In calculating the position of the various lines it does so without taking account of the CRs that exist in the host code. One solution to this problem is to keep the code as defined by the host and only apply RemoveCR prior to submitting the code to the interpreter (not implemented). f) DebugProperty.SetValueAsString causes Access violation. DebugProperty.GetPropertyInfo in unit expressions.py works fine. DebugProperty.SetValueAsString on the other hand calls RaiseNotImpl which would also be OK. However my host gets an access violation when calling this method and the code in SetValueAsString is never called (I added a trace statement to check this). Could this be a problem with the C part of PyWin?? This feature works well with other engines. By the way it wouldn't be too difficult to implement this. All you would need is to pass the stackFrame to the __init__ of DebugProperty and then just say in SetValueAsString: exec(self.name+"="+self.value, stackFrame.f_locals, stackFrame.f_globals) with exception handling of course. The followiing are feature requests rather than bugs: g) Partial InvokeEx support for ScriptDispatch It is fairly easy to provide partial InvokeEx support to ScriptDispatch by overriding two mehtods in StrictDynamicPolicy class StrictDynamicPolicy(win32com.server.policy.DynamicPolicy): def _wrap_(self, object): win32com.server.policy.DynamicPolicy._wrap_(self, object) if hasattr(self._obj_, 'scriptNamespace'): for name in dir(self._obj_.scriptNamespace): self._dyn_dispid_to_name_[self._getdispid_(name,0)] = name def _getmembername_(self, dispid): try: return str(self._dyn_dispid_to_name_[dispid]) except KeyError: raise COMException(scode=winerror.DISP_E_UNKNOWNNAME, desc="Name not found") h) Module support Currently ParseScriptText in Framework.py ignores the second argument ItemName and compiles all code in the module globalNameSpaceModule. The proper (Microsoft Engines like) way of handling ItemName is to compile into globalNameSpaceModule only when ItemName is None and create new modules for different ItemNames. The globalNameSpaceModule should be imported into the other modules so that all members of globalNameSpaceModule are visible in other modules. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=551954&aid=1119799&group_id=78018 |