private int BindWithTimeout() { 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 { if ((enum_BP_LOCATION_TYPE)_bpRequestInfo.bpLocation.bpLocationType == enum_BP_LOCATION_TYPE.BPLT_DATA_STRING) { lock (_engine.DebuggedProcess.DataBreakpointVariables) { string addressName = HostMarshal.GetDataBreakpointStringForIntPtr(_bpRequestInfo.bpLocation.unionmember3); if (!_engine.DebuggedProcess.DataBreakpointVariables.Contains(addressName)) // might need to expand condition { _engine.DebuggedProcess.DataBreakpointVariables.Add(addressName); } } } return(Constants.S_OK); } }
// 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)); } }