Implementing CTIStackFrame
In a typical program that uses function calls, a stack frame would be created for each function call. In more general terms, a frame represents a local execution context that can contain local variables and other pertinent data (for example, in a frame associated with a function call, the function arguments and the return address would also be part of the frame). In the Debugging SDK, this frame is called a stack frame (whether or not the program being debugged uses a stack).
In TextInterpreter, there is only one execution context and therefore only one frame. This stack frame is represented by the IDebugStackFrame2 interface and is implemented on the CTIStackFrame class.
To implement CStackFrame
In Solution Explorer, right-click the TextInterpreter project, click Add Clas , click an ATL Simple Object, and click Add.
For the Short name, type TIStackFrame.
Clear the Attributed option.
Change the Interface to IDebugStackFrame2.
Click Next or click the Options link on the left.
Change the Interface from Dual to Custom.
Click Finish to add the ATL object to the project.
Open the TextInterpreter.idl file and remove the declaration for the interface IDebugStackFrame2, which looks similar to the following (the uuid may be different):
[ object, uuid(958BBCF8-2353-4497-BF19-C326729D6122), helpstring("IDebugStackFrame2 Interface"), pointer_default(unique) ] interface IDebugStackFrame2 : IUnknown{ };
In Class View, right-click the new CTIStackFrame class, click Add Variable, and add a variable with the Variable name m_spDocContext, the Variable type of CComPtr<IDebugDocumentContext2>, and an Access type of protected.
In Class View, right-click the CTIStackFrame class once again and click Add Function to add a function with the Function name Init, a Return type of void, and the following parameter (click Add before clicking Finish). Make sure the .cpp file contains TIStackFrame.cpp.
Parameter type
Parameter name
IDebugDocumentContext2 *
pDocContext
Open TIStackFrame.h, find the new CTIStackFrame class, and add the following bold lines. These are the declarations for the methods on the IDebugStackFrame2 interface.
END_COM_MAP() //////////////////////////////////////////////////////////// // IDebugStackFrame2 STDMETHOD(GetCodeContext)(IDebugCodeContext2 **ppCodeCxt); STDMETHOD(GetDocumentContext)(IDebugDocumentContext2 **ppCxt); STDMETHOD(GetName)(BSTR* pbstrName); STDMETHOD(GetInfo)(FRAMEINFO_FLAGS dwFieldSpec, UINT nRadix, FRAMEINFO *pFrameInfo); STDMETHOD(GetPhysicalStackRange)(UINT64* paddrMin, UINT64* paddrMax); STDMETHOD(GetExpressionContext)(IDebugExpressionContext2 **ppExprCxt); STDMETHOD(GetLanguageInfo)(BSTR* pbstrLanguage, GUID* pguidLanguage); STDMETHOD(GetDebugProperty)(IDebugProperty2 **ppDebugProp); STDMETHOD(EnumProperties)( DEBUGPROP_INFO_FLAGS dwFields, UINT nRadix, REFGUID guidFilter, DWORD dwTimeout, ULONG *pcelt, IEnumDebugPropertyInfo2 **ppepi); STDMETHOD(GetThread)(IDebugThread2** ppThread);
Open the TIStackFrame.cpp file, find the definition for the new CTIStackFrame class, and insert the following bold lines. These are the definitions for the methods on the IDebugStackFrame2 interface.
// CTIStackFrame ////////////////////////////////////////////////////////////////////////////// // IDebugStackFrame2 HRESULT CTIStackFrame::GetCodeContext(IDebugCodeContext2 **ppCodeCxt) { return E_NOTIMPL; } HRESULT CTIStackFrame::GetName(BSTR* pbstrName) { return E_NOTIMPL; } HRESULT CTIStackFrame::GetInfo( FRAMEINFO_FLAGS dwFieldSpec, UINT nRadix, FRAMEINFO *pFrameInfo) { return E_NOTIMPL; } HRESULT CTIStackFrame::GetPhysicalStackRange(UINT64* paddrMin, UINT64* paddrMax) { return E_NOTIMPL; } HRESULT CTIStackFrame::GetExpressionContext(IDebugExpressionContext2 **ppExprCxt) { return E_NOTIMPL; } HRESULT CTIStackFrame::GetLanguageInfo(BSTR* pbstrLanguage, GUID* pguidLanguage) { return E_NOTIMPL; } HRESULT CTIStackFrame::GetDebugProperty(IDebugProperty2 **ppDebugProp) { return E_NOTIMPL; } HRESULT CTIStackFrame::EnumProperties( DEBUGPROP_INFO_FLAGS dwFields, UINT nRadix, REFGUID guidFilter, DWORD dwTimeout, ULONG *pcelt, IEnumDebugPropertyInfo2 **ppepi) { return E_NOTIMPL; } HRESULT CTIStackFrame::GetThread(IDebugThread2** ppThread) { return E_NOTIMPL; } HRESULT CTIStackFrame::GetDocumentContext(IDebugDocumentContext2 **ppCxt) { *ppCxt = m_spDocContext; (*ppCxt)->AddRef(); return S_OK; }
In TIStackFrame.cpp, find the definition for CTIStackFrame::Init and add the following bold line:
CTIStackFrame::Init(IDebugDocumentContext2 *pDocContext) { m_spDocContext = pDocContext; }
Build the project to make sure there are no errors.