// Gets the breakpoint resolution information that describes this breakpoint. int IDebugBreakpointResolution2.GetResolutionInfo(enum_BPRESI_FIELDS dwFields, BP_RESOLUTION_INFO[] pBPResolutionInfo) { if ((dwFields & enum_BPRESI_FIELDS.BPRESI_BPRESLOCATION) != 0) { // The sample engine only supports code breakpoints. BP_RESOLUTION_LOCATION location = new BP_RESOLUTION_LOCATION(); location.bpType = (uint)enum_BP_TYPE.BPT_CODE; // The debugger will not QI the IDebugCodeContex2 interface returned here. We must pass the pointer // to IDebugCodeContex2 and not IUnknown. AD7MemoryAddress codeContext = new AD7MemoryAddress(m_engine, m_address); codeContext.SetDocumentContext(m_documentContext); location.unionmember1 = Marshal.GetComInterfaceForObject(codeContext, typeof(IDebugCodeContext2)); pBPResolutionInfo[0].bpResLocation = location; pBPResolutionInfo[0].dwFields |= enum_BPRESI_FIELDS.BPRESI_BPRESLOCATION; } if ((dwFields & enum_BPRESI_FIELDS.BPRESI_PROGRAM) != 0) { pBPResolutionInfo[0].pProgram = (IDebugProgram2)m_engine; pBPResolutionInfo[0].dwFields |= enum_BPRESI_FIELDS.BPRESI_PROGRAM; } return VSConstants.S_OK; }
/// <summary> /// Constructor. /// </summary> /// <param name="fileName"> Short path file name. </param> /// <param name="begPos"> Start position. </param> /// <param name="endPos"> End position. In VSNDK debug engine, both begPos and endPos have the same value. </param> /// <param name="codeContext"> An address in a program's execution stream. </param> public AD7DocumentContext(string fileName, TEXT_POSITION begPos, TEXT_POSITION endPos, AD7MemoryAddress codeContext) { // Need to lengthen the path used by Visual Studio. StringBuilder documentNameSB = new StringBuilder(1024); GetLongPathName(fileName, documentNameSB, documentNameSB.Capacity); m_fileName = documentNameSB.ToString(); m_begPos = begPos; m_endPos = endPos; m_codeContext = codeContext; }
// Retrieves a list of all code contexts associated with this document context. // The engine sample only supports one code context per document context and // the code contexts are always memory addresses. int IDebugDocumentContext2.EnumCodeContexts(out IEnumDebugCodeContexts2 ppEnumCodeCxts) { ppEnumCodeCxts = null; try { AD7MemoryAddress[] codeContexts = new AD7MemoryAddress[1]; codeContexts[0] = m_codeContext; ppEnumCodeCxts = new AD7CodeContextEnum(codeContexts); return VSConstants.S_OK; } catch (Exception e) { return EngineUtils.UnexpectedException(e); } }
/// <summary> /// AD7BoundBreakpoint constructor for file/line breaks. /// </summary> /// <param name="engine"> AD7 Engine. </param> /// <param name="bpReqInfo"> Contains the information required to implement a breakpoint. </param> /// <param name="pendingBreakpoint"> Associated pending breakpoint. </param> public AD7BoundBreakpoint(AD7Engine engine, BP_REQUEST_INFO bpReqInfo, AD7PendingBreakpoint pendingBreakpoint) { if (bpReqInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE) { string documentName; // Get Decument Position and File Name IDebugDocumentPosition2 docPosition = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(bpReqInfo.bpLocation.unionmember2)); docPosition.GetFileName(out documentName); // Need to shorten the path we send to GDB. StringBuilder shortPath = new StringBuilder(1024); GetShortPathName(documentName, shortPath, shortPath.Capacity); // Get the location in the document that the breakpoint is in. TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; docPosition.GetRange(startPosition, endPosition); m_engine = engine; m_bpLocationType = (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE; m_filename = shortPath.ToString(); m_line = startPosition[0].dwLine + 1; m_pendingBreakpoint = pendingBreakpoint; m_enabled = true; m_deleted = false; m_hitCount = 0; m_remoteID = m_engine.BPMgr.RemoteAdd(this); } else if (bpReqInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET) { string func; IDebugFunctionPosition2 funcPosition = (IDebugFunctionPosition2)(Marshal.GetObjectForIUnknown(bpReqInfo.bpLocation.unionmember2)); funcPosition.GetFunctionName(out func); m_engine = engine; m_func = func; m_enabled = true; m_deleted = false; m_hitCount = 0; m_bpLocationType = (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET; m_pendingBreakpoint = pendingBreakpoint; m_remoteID = m_engine.BPMgr.RemoteAdd(this); } // if ((m_remoteID == 0) && (VSNDK.AddIn.VSNDKAddIn.isDebugEngineRunning == false)) if (m_remoteID == 0) { return; } // Set the hit count and condition if (bpReqInfo.bpPassCount.stylePassCount != enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_NONE) SetPassCount(bpReqInfo.bpPassCount); if (bpReqInfo.bpCondition.styleCondition != enum_BP_COND_STYLE.BP_COND_NONE) SetCondition(bpReqInfo.bpCondition); // Get the Line Position sent back from GDB TEXT_POSITION tpos = new TEXT_POSITION(); tpos.dwLine = m_GDB_linePos - 1; uint xAddress = UInt32.Parse(m_GDB_Address.Substring(2), System.Globalization.NumberStyles.HexNumber); AD7MemoryAddress codeContext = new AD7MemoryAddress(m_engine, xAddress); AD7DocumentContext documentContext = new AD7DocumentContext(m_GDB_filename, tpos, tpos, codeContext); m_breakpointResolution = new AD7BreakpointResolution(m_engine, xAddress, documentContext); m_engine.Callback.OnBreakpointBound(this, 0); }
// Gets the code context for this stack frame. The code context represents the current instruction pointer in this stack frame. int IDebugStackFrame2.GetCodeContext(out IDebugCodeContext2 memoryAddress) { memoryAddress = null; try { memoryAddress = new AD7MemoryAddress(m_engine, m_address); return VSConstants.S_OK; } catch (Exception e) { return EngineUtils.UnexpectedException(e); } }
// Returns the document context needed for showing the location of the current instruction pointer public AD7DocumentContext getDocumentContext(string filename, uint line) { // Get the location in the document that the breakpoint is in. TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; startPosition[0].dwLine = line; startPosition[0].dwColumn = 0; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; endPosition[0].dwLine = line; endPosition[0].dwColumn = 0; uint address = 0; AD7MemoryAddress codeContext = new AD7MemoryAddress(m_engine, address); return new AD7DocumentContext(filename, startPosition[0], endPosition[0], codeContext); }
/// <summary> /// AD7BoundBreakpoint constructor for file/line breaks. /// </summary> /// <param name="engine"> AD7 Engine. </param> /// <param name="bpReqInfo"> Contains the information required to implement a breakpoint. </param> /// <param name="pendingBreakpoint"> Associated pending breakpoint. </param> public AD7BoundBreakpoint(AD7Engine engine, BP_REQUEST_INFO bpReqInfo, AD7PendingBreakpoint pendingBreakpoint) { if (bpReqInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE) { string documentName; // Get Decument Position and File Name IDebugDocumentPosition2 docPosition = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(bpReqInfo.bpLocation.unionmember2)); docPosition.GetFileName(out documentName); // Need to shorten the path we send to GDB. StringBuilder shortPath = new StringBuilder(1024); GetShortPathName(documentName, shortPath, shortPath.Capacity); // Get the location in the document that the breakpoint is in. TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; docPosition.GetRange(startPosition, endPosition); m_engine = engine; m_bpLocationType = (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE; m_filename = shortPath.ToString(); m_line = startPosition[0].dwLine + 1; m_pendingBreakpoint = pendingBreakpoint; m_enabled = true; m_deleted = false; m_hitCount = 0; m_remoteID = m_engine.BPMgr.RemoteAdd(this); } else if (bpReqInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET) { string func; IDebugFunctionPosition2 funcPosition = (IDebugFunctionPosition2)(Marshal.GetObjectForIUnknown(bpReqInfo.bpLocation.unionmember2)); funcPosition.GetFunctionName(out func); m_engine = engine; m_func = func; m_enabled = true; m_deleted = false; m_hitCount = 0; m_bpLocationType = (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET; m_pendingBreakpoint = pendingBreakpoint; m_remoteID = m_engine.BPMgr.RemoteAdd(this); } // if ((m_remoteID == 0) && (VSNDK.AddIn.VSNDKAddIn.isDebugEngineRunning == false)) if (m_remoteID == 0) { return; } // Set the hit count and condition if (bpReqInfo.bpPassCount.stylePassCount != enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_NONE) { SetPassCount(bpReqInfo.bpPassCount); } if (bpReqInfo.bpCondition.styleCondition != enum_BP_COND_STYLE.BP_COND_NONE) { SetCondition(bpReqInfo.bpCondition); } // Get the Line Position sent back from GDB TEXT_POSITION tpos = new TEXT_POSITION(); tpos.dwLine = m_GDB_linePos - 1; uint xAddress = UInt32.Parse(m_GDB_Address.Substring(2), System.Globalization.NumberStyles.HexNumber); AD7MemoryAddress codeContext = new AD7MemoryAddress(m_engine, xAddress); AD7DocumentContext documentContext = new AD7DocumentContext(m_GDB_filename, tpos, tpos, codeContext); m_breakpointResolution = new AD7BreakpointResolution(m_engine, xAddress, documentContext); m_engine.Callback.OnBreakpointBound(this, 0); }
// Get the document context for this pending breakpoint. A document context is a abstract representation of a source file // location. public AD7DocumentContext GetDocumentContext(uint address) { IDebugDocumentPosition2 docPosition = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(m_bpRequestInfo.bpLocation.unionmember2)); string documentName; EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); // Get the location in the document that the breakpoint is in. TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); AD7MemoryAddress codeContext = new AD7MemoryAddress(m_engine, address); return new AD7DocumentContext(documentName, startPosition[0], startPosition[0], codeContext); }
// Adds a specified value to the current context's address to create a new context. public int Add(ulong dwCount, out IDebugMemoryContext2 newAddress) { newAddress = new AD7MemoryAddress(m_engine, (uint)dwCount + m_address); return VSConstants.S_OK; }
// Subtracts a specified value from the current context's address to create a new context. public int Subtract(ulong dwCount, out IDebugMemoryContext2 ppMemCxt) { ppMemCxt = new AD7MemoryAddress(m_engine, (uint)dwCount - m_address); return VSConstants.S_OK; }
/// <summary> /// Constructor. /// </summary> /// <param name="fileName"> Short path file name. </param> /// <param name="begPos"> Start position. </param> /// <param name="endPos"> End position. In VSNDK debug engine, both begPos and endPos have the same value. </param> /// <param name="codeContext"> An address in a program's execution stream. </param> public AD7DocumentContext(string fileName, TEXT_POSITION begPos, TEXT_POSITION endPos, AD7MemoryAddress codeContext) { // Need to lengthen the path used by Visual Studio. StringBuilder documentNameSB = new StringBuilder(1024); GetLongPathName(fileName, documentNameSB, documentNameSB.Capacity); m_fileName = documentNameSB.ToString(); m_begPos = begPos; m_endPos = endPos; m_codeContext = codeContext; }