home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 May / PCWorld_2002-05_cd.bin / Software / TemaCD / activepython / ActivePython-2.1.1.msi / Python21_win32comext_axdebug_debugger.py < prev    next >
Encoding:
Python Source  |  2001-07-26  |  6.2 KB  |  203 lines

  1. import sys, traceback, string
  2.  
  3. from win32com.axscript import axscript
  4. from win32com.axdebug import codecontainer, axdebug, gateways, documents, contexts, adb, expressions
  5. from win32com.axdebug.util import trace, _wrap, _wrap_remove
  6.  
  7. import pythoncom
  8. import win32api, winerror
  9. import os
  10.  
  11. currentDebugger = None
  12.  
  13. class ModuleTreeNode:
  14.     """Helper class for building a module tree
  15.     """
  16.     def __init__(self, module):
  17.         modName = module.__name__
  18.         self.moduleName = modName
  19.         self.module = module
  20.         self.realNode = None
  21.         self.cont = codecontainer.SourceModuleContainer(module)
  22.     def __repr__(self):
  23.         return "<ModuleTreeNode wrapping %s>" % (self.module)
  24.     def Attach(self, parentRealNode):
  25.         self.realNode.Attach(parentRealNode)
  26.         
  27.     def Close(self):
  28.         self.module = None
  29.         self.cont = None
  30.         self.realNode = None
  31.  
  32. def BuildModule(module, built_nodes, rootNode, create_node_fn, create_node_args ):
  33.     if module:
  34.         keep = module.__name__
  35.         keep = keep and (built_nodes.get(module) is None)
  36.         if keep and hasattr(module, '__file__'):
  37.             keep = string.lower(os.path.splitext(module.__file__)[1]) not in [".pyd", ".dll"]
  38. #        keep = keep and module.__name__=='__main__'
  39.     if module and keep:
  40. #        print "keeping", module.__name__
  41.         node = ModuleTreeNode(module)
  42.         built_nodes[module] = node
  43.         realNode = apply(create_node_fn, (node,)+create_node_args)
  44.         node.realNode = realNode
  45.         
  46.         # Split into parent nodes.
  47.         parts = string.split(module.__name__, '.')
  48.         if parts[-1][:8]=='__init__': parts = parts[:-1]
  49.         parent = string.join(parts[:-1], '.')
  50.         parentNode = rootNode
  51.         if parent:
  52.             parentModule = sys.modules[parent]
  53.             BuildModule(parentModule, built_nodes, rootNode, create_node_fn, create_node_args)
  54.             parentNode = built_nodes[parentModule].realNode
  55.         node.Attach(parentNode)
  56.  
  57. def RefreshAllModules(builtItems, rootNode, create_node, create_node_args):
  58.     for module in sys.modules.values():
  59.         BuildModule(module, builtItems, rootNode, create_node, create_node_args)
  60.         
  61. # realNode = pdm.CreateDebugDocumentHelper(None) # DebugDocumentHelper node?
  62. # app.CreateApplicationNode() # doc provider node.
  63.  
  64. class CodeContainerProvider(documents.CodeContainerProvider):
  65.     def __init__(self, axdebugger):
  66.         self.axdebugger = axdebugger
  67.         documents.CodeContainerProvider.__init__(self)
  68.         self.currentNumModules = len(sys.modules)
  69.         self.nodes = {}
  70.         self.axdebugger.RefreshAllModules(self.nodes, self)
  71.         
  72.     def FromFileName(self, fname):
  73. ### It appears we cant add modules during a debug session!
  74. #        if self.currentNumModules != len(sys.modules):
  75. #            self.axdebugger.RefreshAllModules(self.nodes, self)
  76. #            self.currentNumModules = len(sys.modules)
  77. #        for key in self.ccsAndNodes.keys():
  78. #            print "File:", key
  79.         return documents.CodeContainerProvider.FromFileName(self, fname)
  80.  
  81.     def Close(self):
  82.         documents.CodeContainerProvider.Close(self)
  83.         self.axdebugger = None
  84.         print "Closing %d nodes" % (len(self.nodes))
  85.         for node in self.nodes.values():
  86.             node.Close()
  87.         self.nodes = {}
  88.  
  89. class OriginalInterfaceMaker:
  90.     def MakeInterfaces(self, pdm):
  91.         app = self.pdm.CreateApplication()
  92.         self.cookie = pdm.AddApplication(app)
  93.         root = app.GetRootNode()
  94.         return app, root
  95.  
  96.     def CloseInterfaces(self, pdm):
  97.         pdm.RemoveApplication(self.cookie)
  98.  
  99. class SimpleHostStyleInterfaceMaker:
  100.     def MakeInterfaces(self, pdm):
  101.         app = pdm.GetDefaultApplication()
  102.         root = app.GetRootNode()
  103.         return app, root
  104.     
  105.     def CloseInterfaces(self, pdm):
  106.         pass
  107.     
  108.  
  109. class AXDebugger:
  110.     def __init__(self, interfaceMaker = None, processName = None):
  111.         if processName is None: processName = "Python Process"
  112.         if interfaceMaker is None: interfaceMaker = SimpleHostStyleInterfaceMaker()
  113.  
  114.         self.pydebugger = adb.Debugger()
  115.         
  116.         self.pdm=pythoncom.CoCreateInstance(axdebug.CLSID_ProcessDebugManager,None,pythoncom.CLSCTX_ALL, axdebug.IID_IProcessDebugManager)
  117.  
  118.         self.app, self.root = interfaceMaker.MakeInterfaces(self.pdm)
  119.         self.app.SetName(processName)
  120.         self.interfaceMaker = interfaceMaker
  121.  
  122.         expressionProvider = _wrap(expressions.ProvideExpressionContexts(), axdebug.IID_IProvideExpressionContexts)
  123.         self.expressionCookie = self.app.AddGlobalExpressionContextProvider(expressionProvider)
  124.         
  125.         contProvider = CodeContainerProvider(self)
  126.         self.pydebugger.AttachApp(self.app, contProvider)
  127.  
  128.     def Break(self):
  129.         # Get the frame we start debugging from - this is the frame 1 level up
  130.         try:
  131.             1 + ''
  132.         except:
  133.             frame = sys.exc_info()[2].tb_frame.f_back
  134.  
  135.         # Get/create the debugger, and tell it to break.
  136.         self.app.StartDebugSession()
  137. #        self.app.CauseBreak()
  138.  
  139.         self.pydebugger.SetupAXDebugging(None, frame)
  140.         self.pydebugger.set_trace()
  141.  
  142.     def Close(self):
  143.         self.pydebugger.ResetAXDebugging()
  144.         self.interfaceMaker.CloseInterfaces(self.pdm)
  145.         self.pydebugger.CloseApp()
  146.         self.app.RemoveGlobalExpressionContextProvider(self.expressionCookie)
  147.         self.expressionCookie = None
  148.  
  149.         self.pdm = None
  150.         self.app = None
  151.         self.pydebugger = None
  152.         self.root = None
  153.  
  154.     def RefreshAllModules(self, nodes, containerProvider):
  155.         RefreshAllModules(nodes, self.root, self.CreateApplicationNode, (containerProvider,))
  156.  
  157.     def CreateApplicationNode(self, node, containerProvider):
  158.         realNode = self.app.CreateApplicationNode()
  159.         
  160.         document = documents.DebugDocumentText(node.cont)
  161.         document = _wrap(document, axdebug.IID_IDebugDocument)
  162.  
  163.         node.cont.debugDocument = document
  164.  
  165.         provider = documents.DebugDocumentProvider(document)
  166.         provider = _wrap(provider, axdebug.IID_IDebugDocumentProvider)
  167.         realNode.SetDocumentProvider(provider)
  168.         
  169.         containerProvider.AddCodeContainer(node.cont, realNode)
  170.         return realNode
  171.  
  172. def _GetCurrentDebugger():
  173.     global currentDebugger
  174.     if currentDebugger is None:
  175.         currentDebugger = AXDebugger()
  176.     return currentDebugger
  177.     
  178. def Break():
  179.     _GetCurrentDebugger().Break()
  180.     
  181. brk = Break
  182. set_trace = Break
  183.         
  184. def dosomethingelse():
  185.     a=2
  186.     b = "Hi there"
  187.     
  188. def dosomething():
  189.     a=1
  190.     b=2
  191.     dosomethingelse()
  192.  
  193. def test():
  194.     Break()
  195.     raw_input("Waiting...")
  196.     dosomething()
  197.     print "Done"
  198.  
  199. if __name__=='__main__':
  200.     print "About to test the debugging interfaces!"
  201.     test()
  202.     print " %d/%d com objects still alive" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
  203.