public BreakpointLocationCodeFunctionOffset(BP_LOCATION location, bool releaseComObjects) { Contract.Requires <ArgumentException>((enum_BP_LOCATION_TYPE)location.bpLocationType == enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET); try { if (location.unionmember1 != IntPtr.Zero) { _context = Marshal.PtrToStringBSTR(location.unionmember1); } if (location.unionmember2 != IntPtr.Zero) { _functionPosition = Marshal.GetObjectForIUnknown(location.unionmember2) as IDebugFunctionPosition2; } } finally { if (releaseComObjects) { if (location.unionmember1 != IntPtr.Zero) { Marshal.FreeBSTR(location.unionmember1); } if (location.unionmember2 != IntPtr.Zero) { Marshal.Release(location.unionmember2); } } } }
public static IntPtr RegisterFunctionPosition(IDebugFunctionPosition2 functionPosition) { if (functionPosition == null) { throw new ArgumentNullException("functionPosition"); } lock (s_functionPositions) { return((IntPtr)s_functionPositions.Create(functionPosition)); } }
public BreakpointLocationCodeFunctionOffset(BP_LOCATION location, bool releaseComObjects) { Contract.Requires<ArgumentException>((enum_BP_LOCATION_TYPE)location.bpLocationType == enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET); try { if (location.unionmember1 != IntPtr.Zero) _context = Marshal.PtrToStringBSTR(location.unionmember1); if (location.unionmember2 != IntPtr.Zero) _functionPosition = Marshal.GetObjectForIUnknown(location.unionmember2) as IDebugFunctionPosition2; } finally { if (releaseComObjects) { if (location.unionmember1 != IntPtr.Zero) Marshal.FreeBSTR(location.unionmember1); if (location.unionmember2 != IntPtr.Zero) Marshal.Release(location.unionmember2); } } }
internal async Task BindAsync() { if (CanBind()) { string documentName = null; string functionName = null; TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; string condition = null; string address = null; ulong codeAddress = 0; uint size = 0; IEnumerable <Checksum> checksums = null; lock (_boundBreakpoints) { if (_bp != null) // already bound { Debug.Fail("Breakpoint already bound"); return; } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_CONDITION) != 0 && _bpRequestInfo.bpCondition.styleCondition == enum_BP_COND_STYLE.BP_COND_WHEN_TRUE) { condition = _bpRequestInfo.bpCondition.bstrCondition; } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_BPLOCATION) != 0) { switch ((enum_BP_LOCATION_TYPE)_bpRequestInfo.bpLocation.bpLocationType) { case enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET: { IDebugFunctionPosition2 functionPosition = HostMarshal.GetDebugFunctionPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); EngineUtils.CheckOk(functionPosition.GetFunctionName(out functionName)); break; } case enum_BP_LOCATION_TYPE.BPLT_CODE_CONTEXT: { IDebugCodeContext2 codePosition = HostMarshal.GetDebugCodeContextForIntPtr(_bpRequestInfo.bpLocation.unionmember1); if (!(codePosition is AD7MemoryAddress)) { goto default; // context is not from this engine } codeAddress = ((AD7MemoryAddress)codePosition).Address; break; } case enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE: { IDebugDocumentPosition2 docPosition = HostMarshal.GetDocumentPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); // Get the name of the document that the breakpoint was put in EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); // Get the location in the document that the breakpoint is in. EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); // Get the document checksum // TODO: This and all other AD7 interface calls need to be moved so that they are only // executed from the main thread. // Github issue: https://github.com/Microsoft/MIEngine/issues/350 if (_engine.DebuggedProcess.MICommandFactory.SupportsBreakpointChecksums()) { try { checksums = GetSHA1Checksums(); } catch (Exception) { // If we fail to get a checksum there's nothing else we can do } } break; } case enum_BP_LOCATION_TYPE.BPLT_DATA_STRING: { address = HostMarshal.GetDataBreakpointStringForIntPtr(_bpRequestInfo.bpLocation.unionmember3); size = (uint)_bpRequestInfo.bpLocation.unionmember4; if (condition != null) { goto default; // mi has no conditions on watchpoints } break; } default: { this.SetError(new AD7ErrorBreakpoint(this, ResourceStrings.UnsupportedBreakpoint), true); return; } } } } PendingBreakpoint.BindResult bindResult; // Bind all breakpoints that match this source and line number. if (documentName != null) { bindResult = await PendingBreakpoint.Bind(documentName, startPosition[0].dwLine + 1, startPosition[0].dwColumn, _engine.DebuggedProcess, condition, _enabled, checksums, this); } else if (functionName != null) { bindResult = await PendingBreakpoint.Bind(functionName, _engine.DebuggedProcess, condition, _enabled, this); } else if (codeAddress != 0) { bindResult = await PendingBreakpoint.Bind(codeAddress, _engine.DebuggedProcess, condition, _enabled, this); } else { bindResult = await PendingBreakpoint.Bind(address, size, _engine.DebuggedProcess, condition, this); } lock (_boundBreakpoints) { if (bindResult.PendingBreakpoint != null) { _bp = bindResult.PendingBreakpoint; // an MI breakpoint object exists: TODO: lock? } if (bindResult.BoundBreakpoints == null || bindResult.BoundBreakpoints.Count == 0) { this.SetError(new AD7ErrorBreakpoint(this, bindResult.ErrorMessage), true); } else { Debug.Assert(_bp != null); foreach (BoundBreakpoint bp in bindResult.BoundBreakpoints) { AddBoundBreakpoint(bp); } } } } }
// Binds this pending breakpoint to one or more code locations. int IDebugPendingBreakpoint2.Bind() { try { if (CanBind()) { // Make sure that HostMarshal calls happen on main thread instead of poll thread. lock (_boundBreakpoints) { if (_bp != null) // already bound { Debug.Fail("Breakpoint already bound"); return(Constants.S_FALSE); } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_CONDITION) != 0 && _bpRequestInfo.bpCondition.styleCondition == enum_BP_COND_STYLE.BP_COND_WHEN_TRUE) { _condition = _bpRequestInfo.bpCondition.bstrCondition; } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_BPLOCATION) != 0) { switch ((enum_BP_LOCATION_TYPE)_bpRequestInfo.bpLocation.bpLocationType) { case enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET: try { IDebugFunctionPosition2 functionPosition = HostMarshal.GetDebugFunctionPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); EngineUtils.CheckOk(functionPosition.GetFunctionName(out _functionName)); } finally { HostMarshal.Release(_bpRequestInfo.bpLocation.unionmember2); } break; case enum_BP_LOCATION_TYPE.BPLT_CODE_CONTEXT: try { IDebugCodeContext2 codePosition = HostMarshal.GetDebugCodeContextForIntPtr(_bpRequestInfo.bpLocation.unionmember1); if (!(codePosition is AD7MemoryAddress)) { goto default; // context is not from this engine } _codeAddress = ((AD7MemoryAddress)codePosition).Address; } finally { HostMarshal.Release(_bpRequestInfo.bpLocation.unionmember1); } break; case enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE: try { IDebugDocumentPosition2 docPosition = HostMarshal.GetDocumentPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); // Get the name of the document that the breakpoint was put in EngineUtils.CheckOk(docPosition.GetFileName(out _documentName)); // Get the location in the document that the breakpoint is in. EngineUtils.CheckOk(docPosition.GetRange(_startPosition, _endPosition)); } finally { HostMarshal.Release(_bpRequestInfo.bpLocation.unionmember2); } // Get the document checksum if (_engine.DebuggedProcess.MICommandFactory.SupportsBreakpointChecksums()) { try { _checksums = GetSHA1Checksums(); } catch (Exception) { // If we fail to get a checksum there's nothing else we can do } } break; case enum_BP_LOCATION_TYPE.BPLT_DATA_STRING: _address = HostMarshal.GetDataBreakpointStringForIntPtr(_bpRequestInfo.bpLocation.unionmember3); _size = (uint)_bpRequestInfo.bpLocation.unionmember4; if (_condition != null) { goto default; // mi has no conditions on watchpoints } break; default: this.SetError(new AD7ErrorBreakpoint(this, ResourceStrings.UnsupportedBreakpoint), true); return(Constants.S_FALSE); } } } Task bindTask = null; _engine.DebuggedProcess.WorkerThread.RunOperation(() => { bindTask = _engine.DebuggedProcess.AddInternalBreakAction(this.BindAsync); }); bindTask.Wait(_engine.GetBPLongBindTimeout()); if (!bindTask.IsCompleted) { //send a low severity warning bp. This will allow the UI to respond quickly, and if the mi debugger doesn't end up binding, this warning will get //replaced by the real mi debugger error text this.SetError(new AD7ErrorBreakpoint(this, ResourceStrings.LongBind, enum_BP_ERROR_TYPE.BPET_SEV_LOW | enum_BP_ERROR_TYPE.BPET_TYPE_WARNING), true); return(Constants.S_FALSE); } else { return(Constants.S_OK); } } else { // The breakpoint could not be bound. This may occur for many reasons such as an invalid location, an invalid expression, etc... _engine.Callback.OnBreakpointError(_BPError); return(Constants.S_FALSE); } } catch (MIException e) { return(e.HResult); } catch (AggregateException e) { if (e.GetBaseException() is InvalidCoreDumpOperationException) { return(AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED); } else { return(EngineUtils.UnexpectedException(e)); } } catch (InvalidCoreDumpOperationException) { return(AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED); } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public virtual int EvaluateBreakpointLocation(out DebuggeeDocumentContext documentContext, out DebuggeeCodeContext codeContext, out string location) { LoggingUtils.PrintFunction(); documentContext = null; codeContext = null; location = string.Empty; try { switch (m_breakpointRequestInfo.bpLocation.bpLocationType) { case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE: { // // Specifies the location type of the breakpoint as a line of source code. // string fileName; IDebugDocumentPosition2 documentPostion = (IDebugDocumentPosition2)Marshal.GetObjectForIUnknown(m_breakpointRequestInfo.bpLocation.unionmember2); LoggingUtils.RequireOk(documentPostion.GetFileName(out fileName)); bool fileInCurrentProject = true; // TODO if (File.Exists(fileName) && fileInCurrentProject) { TEXT_POSITION [] startPos = new TEXT_POSITION [1]; TEXT_POSITION [] endPos = new TEXT_POSITION [1]; LoggingUtils.RequireOk(documentPostion.GetRange(startPos, endPos)); documentContext = new DebuggeeDocumentContext(m_breakpointManager.Engine, fileName, startPos [0], endPos [0]); location = string.Format("\"{0}:{1}\"", fileName, startPos [0].dwLine + 1); } else { throw new NotImplementedException(); } break; } case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET: { // // Specifies the location type of the breakpoint as a code function offset. // string function = string.Empty; IDebugFunctionPosition2 functionPosition = (IDebugFunctionPosition2)Marshal.GetObjectForIUnknown(m_breakpointRequestInfo.bpLocation.unionmember2); TEXT_POSITION [] textPos = new TEXT_POSITION [1]; LoggingUtils.RequireOk(functionPosition.GetFunctionName(out function)); LoggingUtils.RequireOk(functionPosition.GetOffset(textPos)); if (!string.IsNullOrEmpty(function)) { location = function; } break; } case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_CONTEXT: { // // Specifies the location type of the breakpoint as a code context. // codeContext = ((IDebugCodeContext2)Marshal.GetObjectForIUnknown(m_breakpointRequestInfo.bpLocation.unionmember1)) as DebuggeeCodeContext; if (codeContext != null) { location = codeContext.Address.ToString(); } break; } case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_STRING: { // // Specifies the location type of the breakpoint as a code string. // throw new NotImplementedException(); } case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_ADDRESS: { // // Specifies the location type of the breakpoint as a code address. // string address = Marshal.PtrToStringBSTR(m_breakpointRequestInfo.bpLocation.unionmember4); if (!string.IsNullOrEmpty(address)) { location = address; } break; } case (uint)enum_BP_LOCATION_TYPE.BPLT_DATA_STRING: { // // Specifies the location type of the breakpoint as a data string. // string dataExpression = Marshal.PtrToStringBSTR(m_breakpointRequestInfo.bpLocation.unionmember3); if (!string.IsNullOrEmpty(dataExpression)) { location = dataExpression; } break; } default: { break; } } return(Constants.S_OK); } catch (NotImplementedException e) { LoggingUtils.HandleException(e); return(Constants.E_NOTIMPL); } catch (Exception e) { LoggingUtils.HandleException(e); return(Constants.E_FAIL); } }
internal async Task BindAsync() { if (CanBind()) { string documentName = null; string functionName = null; TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; string condition = null; lock (_boundBreakpoints) { if (_bp != null) // already bound { Debug.Fail("Breakpoint already bound"); return; } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_BPLOCATION) != 0) { if (_bpRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET) { IDebugFunctionPosition2 functionPosition = HostMarshal.GetDebugFunctionPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); EngineUtils.CheckOk(functionPosition.GetFunctionName(out functionName)); } else if (_bpRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE) { IDebugDocumentPosition2 docPosition = HostMarshal.GetDocumentPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); // Get the name of the document that the breakpoint was put in EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); // Get the location in the document that the breakpoint is in. EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); } } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_CONDITION) != 0 && _bpRequestInfo.bpCondition.styleCondition == enum_BP_COND_STYLE.BP_COND_WHEN_TRUE) { condition = _bpRequestInfo.bpCondition.bstrCondition; } } PendingBreakpoint.BindResult bindResult; // Bind all breakpoints that match this source and line number. if (documentName != null) { bindResult = await PendingBreakpoint.Bind(documentName, startPosition[0].dwLine + 1, startPosition[0].dwColumn, _engine.DebuggedProcess, condition, this); } else { bindResult = await PendingBreakpoint.Bind(functionName, _engine.DebuggedProcess, condition, this); } lock (_boundBreakpoints) { if (bindResult.PendingBreakpoint != null) { _bp = bindResult.PendingBreakpoint; // an MI breakpoint object exists: TODO: lock? } if (bindResult.BoundBreakpoints == null || bindResult.BoundBreakpoints.Count == 0) { _BPError = new AD7ErrorBreakpoint(this, bindResult.ErrorMessage); _engine.Callback.OnBreakpointError(_BPError); } else { Debug.Assert(_bp != null); foreach (BoundBreakpoint bp in bindResult.BoundBreakpoints) { AddBoundBreakpoint(bp); } } } } }
public int Bind() { if (_deleted) { return(AD7Constants.E_BP_DELETED); } switch ((enum_BP_LOCATION_TYPE)_requestInfo.bpLocation.bpLocationType) { case enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE: IDebugDocumentPosition2 documentPosition = _marshal.GetDocumentPositionFromIntPtr(_requestInfo.bpLocation.unionmember2); if (documentPosition.GetFileName(out string fileName) != 0) { SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noSourceFilename); return(VSConstants.S_FALSE); } TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; // TODO: Check if we need the end position or not. This might // matter when setting a breakpoint on a comment. It's possible LLDB will just // handle this for us and we don't need to worry about the end position. if (documentPosition.GetRange(startPosition, null) != VSConstants.S_OK) { SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noSourceLineNumber); return(VSConstants.S_FALSE); } // Visual Studio uses a zero based index for line numbers, where LLDB uses a one // based index for line numbers. We need to add one to the line number here to // convert visual studio line numbers to LLDB line numbers. _lldbBreakpoint = _target.BreakpointCreateByLocation(fileName, startPosition[0].dwLine + 1); break; case enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET: IDebugFunctionPosition2 functionPosition = _marshal.GetFunctionPositionFromIntPtr(_requestInfo.bpLocation.unionmember2); uint offset = 0; if (functionPosition.GetFunctionName(out string functionName) != 0) { SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noFunctionName); return(VSConstants.S_FALSE); } MatchCollection matches = _funcOffsetRegex.Matches(functionName); if (matches.Count == 1) { functionName = matches[0].Groups["name"].Value; string offsetString = matches[0].Groups["offset"].Value; if (!string.IsNullOrWhiteSpace(offsetString)) { offset = uint.Parse(offsetString); } } if (offset > 0) { BreakpointErrorPair breakpointErrorPair = _target.CreateFunctionOffsetBreakpoint(functionName, offset); _lldbBreakpoint = breakpointErrorPair.breakpoint; if (_lldbBreakpoint == null) { switch (breakpointErrorPair.error) { case BreakpointError.NoFunctionFound: SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noFunctionFound); break; case BreakpointError.NoFunctionLocation: SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _breakpointLocationNotSet); break; case BreakpointError.PositionNotAvailable: SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _positionNotAvailable); break; default: SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _positionNotAvailable); break; } return(VSConstants.S_FALSE); } } else { _lldbBreakpoint = _target.BreakpointCreateByName(functionName); } break; case enum_BP_LOCATION_TYPE.BPLT_CODE_CONTEXT: IDebugCodeContext2 codeContext = _marshal.GetCodeContextFromIntPtr(_requestInfo.bpLocation.unionmember1); if (codeContext == null) { SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noCodeContext); return(VSConstants.S_FALSE); } ulong address = codeContext.GetAddress(); _lldbBreakpoint = _target.BreakpointCreateByAddress(address); break; case enum_BP_LOCATION_TYPE.BPLT_CODE_ADDRESS: string strAddress = _marshal.GetStringFromIntPtr(_requestInfo.bpLocation.unionmember4); if (strAddress == null) { SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noCodeAddress); return(VSConstants.S_FALSE); } ulong address2 = Convert.ToUInt64(strAddress, 16); _lldbBreakpoint = _target.BreakpointCreateByAddress(address2); break; default: SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _breakpointNotSupported); return(VSConstants.S_FALSE); } if (_lldbBreakpoint == null) { SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _breakpointNotSet); return(VSConstants.S_FALSE); } UpdateLocations(); _breakpointManager.RegisterPendingBreakpoint(Self); return(_boundBreakpoints.Count == 0 ? VSConstants.S_FALSE : VSConstants.S_OK); }
/// <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); }
// Binds this pending breakpoint to one or more code locations. int IDebugPendingBreakpoint2.Bind() { try { if (CanBind()) { // Make sure that HostMarshal calls happen on main thread instead of poll thread. lock (_boundBreakpoints) { if (_bp != null) // already bound { Debug.Fail("Breakpoint already bound"); return(Constants.S_FALSE); } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_CONDITION) != 0 && _bpRequestInfo.bpCondition.styleCondition == enum_BP_COND_STYLE.BP_COND_WHEN_TRUE) { _condition = _bpRequestInfo.bpCondition.bstrCondition; } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_BPLOCATION) != 0) { switch ((enum_BP_LOCATION_TYPE)_bpRequestInfo.bpLocation.bpLocationType) { case enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET: try { IDebugFunctionPosition2 functionPosition = HostMarshal.GetDebugFunctionPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); EngineUtils.CheckOk(functionPosition.GetFunctionName(out _functionName)); } finally { HostMarshal.Release(_bpRequestInfo.bpLocation.unionmember2); } break; case enum_BP_LOCATION_TYPE.BPLT_CODE_CONTEXT: try { IDebugCodeContext2 codePosition = HostMarshal.GetDebugCodeContextForIntPtr(_bpRequestInfo.bpLocation.unionmember1); if (!(codePosition is AD7MemoryAddress)) { goto default; // context is not from this engine } _codeAddress = ((AD7MemoryAddress)codePosition).Address; } finally { HostMarshal.Release(_bpRequestInfo.bpLocation.unionmember1); } break; case enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE: try { IDebugDocumentPosition2 docPosition = HostMarshal.GetDocumentPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); // Get the name of the document that the breakpoint was put in EngineUtils.CheckOk(docPosition.GetFileName(out _documentName)); // Get the location in the document that the breakpoint is in. EngineUtils.CheckOk(docPosition.GetRange(_startPosition, _endPosition)); } finally { HostMarshal.Release(_bpRequestInfo.bpLocation.unionmember2); } // Get the document checksum if (_engine.DebuggedProcess.MICommandFactory.SupportsBreakpointChecksums()) { try { _checksums = GetSHA1Checksums(); } catch (Exception) { // If we fail to get a checksum there's nothing else we can do } } break; case enum_BP_LOCATION_TYPE.BPLT_DATA_STRING: string address = HostMarshal.GetDataBreakpointStringForIntPtr(_bpRequestInfo.bpLocation.unionmember3); if (address.Contains(",")) { this.AddressId = address; _address = address.Split(',')[0]; } else { this.AddressId = null; _address = address; } _size = (uint)_bpRequestInfo.bpLocation.unionmember4; if (_condition != null) { goto default; // mi has no conditions on watchpoints } break; default: this.SetError(new AD7ErrorBreakpoint(this, ResourceStrings.UnsupportedBreakpoint), true); return(Constants.S_FALSE); } } } if (!_enabled && IsHardwareBreakpoint) { return(Constants.S_OK); } return(BindWithTimeout()); } else { // The breakpoint could not be bound. This may occur for many reasons such as an invalid location, an invalid expression, etc... _engine.Callback.OnBreakpointError(_BPError); return(Constants.S_FALSE); } } catch (MIException e) { return(e.HResult); } catch (AggregateException e) { if (e.GetBaseException() is InvalidCoreDumpOperationException) { return(AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED); } else { return(EngineUtils.UnexpectedException(e)); } } catch (InvalidCoreDumpOperationException) { return(AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED); } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } }