Поделиться через


Implementing IDebugProgram2 and IDebugThread2

In addition to implementing IDebugProgramNode2, the program object implements IDebugProgram2 and IDebugThread2 (since only one thread is running in the program being debugged). In those circumstances where a program would have more than one thread, IDebugThread2 would be implemented in its own class object.

To implement IDebugProgram2 and IDebugThread2

  1. Open the Program.h file and insert the following bold lines:

    class ATL_NO_VTABLE CProgram : 
        public CComObjectRootEx<CComSingleThreadModel>,
        public CComCoClass<CProgram, &CLSID_Program>,
        public IDebugProgram2, 
        public IDebugThread2, 
        public IDebugProgramNode2
    
  2. Also in Program.h, insert the following bold COM mapping macros to the BEGIN_COM_MAP structure. These entries have to be added manually since the interfaces in the previous step were added manually.

    BEGIN_COM_MAP(CProgram)
        COM_INTERFACE_ENTRY(IDebugProgram2) 
        COM_INTERFACE_ENTRY(IDebugThread2) 
        COM_INTERFACE_ENTRY(IDebugProgramNode2)
    END_COM_MAP()
    
  3. Also in Program.h, add the following bold lines. These are the declarations for the methods on the IDebugProgram2 and IDebugThread2 interfaces.

        STDMETHOD(DetachDebugger_V7)(void);
    
        //////////////////////////////////////////////////////////// 
        // IDebugProgram2 
        STDMETHOD(EnumThreads)(IEnumDebugThreads2** ppEnum); 
        STDMETHOD(GetName)(BSTR* pbstrName); 
        STDMETHOD(GetProcess)(IDebugProcess2** ppProcess); 
        STDMETHOD(Terminate)(void); 
        STDMETHOD(Attach)(IDebugEventCallback2* pCallback); 
        STDMETHOD(Detach)(void); 
        STDMETHOD(GetProgramId)(GUID* pguidProgramId); 
        STDMETHOD(GetDebugProperty)(IDebugProperty2** ppProperty); 
        STDMETHOD(Execute)(void); 
        STDMETHOD(Continue)(IDebugThread2 *pThread); 
        STDMETHOD(Step)(IDebugThread2 *pThread, STEPKIND sk, STEPUNIT step); 
        STDMETHOD(CauseBreak)(void); 
        //GetEngineInfo already defined for IDebugProgramNode2 
        STDMETHOD(EnumCodeContexts)( 
            IDebugDocumentPosition2* pDocPos, 
            IEnumDebugCodeContexts2** ppEnum); 
        STDMETHOD(GetMemoryBytes)(IDebugMemoryBytes2** ppMemoryBytes); 
        STDMETHOD(GetDisassemblyStream)( 
            DISASSEMBLY_STREAM_SCOPE dwScope, 
            IDebugCodeContext2* pCodeContext, 
            IDebugDisassemblyStream2** ppDisassemblyStream); 
        STDMETHOD(EnumModules)(IEnumDebugModules2** ppEnum); 
        STDMETHOD(GetENCUpdate)(IDebugENCUpdate** ppUpdate); 
        STDMETHOD(EnumCodePaths)( 
            LPCOLESTR pszHint, 
            IDebugCodeContext2* pStart, 
            IDebugStackFrame2* pFrame, 
            BOOL fSource, 
            IEnumCodePaths2** ppEnum, 
            IDebugCodeContext2** ppSafety); 
        STDMETHOD(WriteDump)(DUMPTYPE DumpType, LPCOLESTR pszCrashDumpUrl); 
        STDMETHOD(CanDetach)(void); 
    
        //////////////////////////////////////////////////////////// 
        // IDebugThread2 
        STDMETHOD(EnumFrameInfo)( 
            FRAMEINFO_FLAGS dwFieldSpec, 
            UINT nRadix, 
            IEnumDebugFrameInfo2 **ppEnum); 
        // GetName already defined for IDebugProgram 
        STDMETHOD(SetThreadName)(LPCOLESTR pszName); 
        STDMETHOD(GetProgram)(IDebugProgram2** ppProgram); 
        STDMETHOD(CanSetNextStatement)( 
            IDebugStackFrame2 *pStackFrame, 
            IDebugCodeContext2 *pCodeContext); 
        STDMETHOD(SetNextStatement)( 
            IDebugStackFrame2 *pStackFrame, 
            IDebugCodeContext2 *pCodeContext); 
        STDMETHOD(GetThreadId)(DWORD* pdwThreadId); 
        STDMETHOD(Suspend)(DWORD *pdwSuspendCount); 
        STDMETHOD(Resume)(DWORD *pdwSuspendCount); 
        STDMETHOD(GetThreadProperties)( 
            THREADPROPERTY_FIELDS dwFields, 
            THREADPROPERTIES *ptp); 
        STDMETHOD(GetLogicalThread)( 
            IDebugStackFrame2 *pStackFrame, 
            IDebugLogicalThread2 **ppLogicalThread); 
    
        DECLARE_PROTECT_FINAL_CONSTRUCT()
    
  4. Open the Program.cpp file and add the following bold lines to the end of the file. These are the definitions for the methods on the IDebugProgram2 and IDebugThread2 interfaces. All return E_NOTIMPL at the moment (only a few will actually be implemented in TextInterpreter).

     ////////////////////////////////////////////////////////////////////////////// 
    // IDebugProgram2 methods 
    HRESULT CProgram::EnumThreads(IEnumDebugThreads2** ppEnum) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::GetName(BSTR* pbstrName) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::GetProcess(IDebugProcess2** ppProcess) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::Terminate(void) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::Attach(IDebugEventCallback2* pCallback) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::Detach(void) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::GetDebugProperty(IDebugProperty2** ppProperty) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::CauseBreak(void) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::EnumCodeContexts(IDebugDocumentPosition2* pDocPos, 
                                       IEnumDebugCodeContexts2** ppEnum) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::GetMemoryBytes(IDebugMemoryBytes2** ppMemoryBytes) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::GetDisassemblyStream(DISASSEMBLY_STREAM_SCOPE dwScope, 
                                           IDebugCodeContext2* pCodeContext, 
                                           IDebugDisassemblyStream2** ppDisassemblyStream) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::EnumModules(IEnumDebugModules2** ppEnum) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::GetENCUpdate(IDebugENCUpdate** ppUpdate) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::EnumCodePaths(LPCOLESTR pszHint, 
                                    IDebugCodeContext2* pStart, 
                                    IDebugStackFrame2* pFrame, 
                                    BOOL fSource, 
                                    IEnumCodePaths2** ppEnum, 
                                    IDebugCodeContext2** ppSafety) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::WriteDump(DUMPTYPE DumpType,LPCOLESTR pszCrashDumpUrl) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::CanDetach(void) 
    { return E_NOTIMPL; } 
    
    HRESULT CProgram::GetProgramId(GUID* pguidProgramId) 
    { 
        //TODO: RETURN PROGRAM GUID 
        return E_NOTIMPL; 
    } 
    
    HRESULT CProgram::Execute(void) 
    { 
        //TODO: BEGIN EXECUTION 
        return E_NOTIMPL; 
    } 
    HRESULT CProgram::Continue(IDebugThread2 *pThread) 
    { 
        //TODO: CONTINUE EXECUTION 
        return E_NOTIMPL; 
    } 
    HRESULT CProgram::Step(IDebugThread2 *pThread, STEPKIND sk, STEPUNIT step) 
    { 
        //TODO: STEP EXECUTION 
        return E_NOTIMPL; 
    } 
    
    ////////////////////////////////////////////////////////////////////////////// 
    //IDebugThread2 methods 
    HRESULT CProgram::SetThreadName(LPCOLESTR pszName) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::GetProgram(IDebugProgram2** ppProgram) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::CanSetNextStatement(IDebugStackFrame2 *pStackFrame, 
                                          IDebugCodeContext2 *pCodeContext) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::SetNextStatement(IDebugStackFrame2 *pStackFrame, 
                                       IDebugCodeContext2 *pCodeContext) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::Suspend(DWORD *pdwSuspendCount) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::Resume(DWORD *pdwSuspendCount) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::GetThreadProperties(THREADPROPERTY_FIELDS dwFields, 
                                          THREADPROPERTIES *ptp) 
    { return E_NOTIMPL; } 
    HRESULT CProgram::GetLogicalThread(IDebugStackFrame2 *pStackFrame, 
                                       IDebugLogicalThread2 **ppLogicalThread) 
    { return E_NOTIMPL; } 
    
    HRESULT CProgram::GetThreadId(DWORD* pdwThreadId) 
    { 
        //TODO: RETURN THREAD ID 
        return E_NOTIMPL; 
    } 
    
    HRESULT CProgram::EnumFrameInfo(FRAMEINFO_FLAGS dwFieldSpec, 
                                    UINT nRadix, 
                                    IEnumDebugFrameInfo2 **ppEnum) 
    { 
        //TODO: RETURN ENUMERATION OF FRAMES 
        return E_NOTIMPL; 
    } 
    
  5. Build the project to make sure there are no errors.

See Also

Tasks

Adding the Program Object