Beispiel #1
0
        private bool CanBind()
        {
            // The sample engine only supports breakpoints on a file and line number or function name. No other types of breakpoints are supported.
            if (_deleted ||
                (_bpRequestInfo.bpLocation.bpLocationType != (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE &&
                 _bpRequestInfo.bpLocation.bpLocationType != (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET))
            {
                _BPError = new AD7ErrorBreakpoint(this, ResourceStrings.UnsupportedBreakpoint, enum_BP_ERROR_TYPE.BPET_GENERAL_ERROR);
                return(false);
            }
            if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_CONDITION) != 0)
            {
                if (!VerifyCondition(_bpRequestInfo.bpCondition))
                {
                    _BPError = new AD7ErrorBreakpoint(this, ResourceStrings.UnsupportedConditionalBreakpoint, enum_BP_ERROR_TYPE.BPET_GENERAL_ERROR);
                    return(false);
                }
            }
            if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_PASSCOUNT) != 0)
            {
                _BPError = new AD7ErrorBreakpoint(this, ResourceStrings.UnsupportedPassCountBreakpoint, enum_BP_ERROR_TYPE.BPET_GENERAL_ERROR);
                return(false);
            }

            return(true);
        }
Beispiel #2
0
        // Binds this pending breakpoint to one or more code locations.
        int IDebugPendingBreakpoint2.Bind()
        {
            try
            {
                if (CanBind())
                {
                    Task bindTask = null;

                    _engine.DebuggedProcess.WorkerThread.RunOperation(() =>
                    {
                        bindTask = _engine.DebuggedProcess.AddInternalBreakAction(this.BindAsync);
                    });

                    bindTask.Wait(250); //wait a quarter of a second

                    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
                        _BPError = new AD7ErrorBreakpoint(this, ResourceStrings.LongBind, enum_BP_ERROR_TYPE.BPET_SEV_LOW | enum_BP_ERROR_TYPE.BPET_TYPE_WARNING);
                        _engine.Callback.OnBreakpointError(_BPError);
                        return(VSConstants.S_FALSE);
                    }
                    else
                    {
                        return(VSConstants.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(VSConstants.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));
            }
        }
Beispiel #3
0
 // The sample engine does not support pass counts on breakpoints.
 int IDebugPendingBreakpoint2.SetPassCount(BP_PASSCOUNT bpPassCount)
 {
     if (bpPassCount.stylePassCount != enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_NONE)
     {
         _BPError = new AD7ErrorBreakpoint(this, ResourceStrings.UnsupportedPassCountBreakpoint, enum_BP_ERROR_TYPE.BPET_GENERAL_ERROR);
         _engine.Callback.OnBreakpointError(_BPError);
         return(VSConstants.E_FAIL);
     }
     return(VSConstants.S_OK);
 }
Beispiel #4
0
        public AD7PendingBreakpoint(IDebugBreakpointRequest2 pBPRequest, AD7Engine engine, BreakpointManager bpManager)
        {
            _pBPRequest = pBPRequest;
            BP_REQUEST_INFO[] requestInfo = new BP_REQUEST_INFO[1];
            EngineUtils.CheckOk(_pBPRequest.GetRequestInfo(enum_BPREQI_FIELDS.BPREQI_BPLOCATION | enum_BPREQI_FIELDS.BPREQI_CONDITION | enum_BPREQI_FIELDS.BPREQI_PASSCOUNT, requestInfo));
            _bpRequestInfo = requestInfo[0];

            _engine           = engine;
            _bpManager        = bpManager;
            _boundBreakpoints = new List <AD7BoundBreakpoint>();

            _enabled       = true;
            _deleted       = false;
            _pendingDelete = false;

            _bp      = null; // no underlying breakpoint created yet
            _BPError = null;
        }
Beispiel #5
0
        int IDebugPendingBreakpoint2.SetCondition(BP_CONDITION bpCondition)
        {
            PendingBreakpoint bp = null;

            lock (_boundBreakpoints)
            {
                if (!VerifyCondition(bpCondition))
                {
                    _BPError = new AD7ErrorBreakpoint(this, ResourceStrings.UnsupportedConditionalBreakpoint, enum_BP_ERROR_TYPE.BPET_GENERAL_ERROR);
                    _engine.Callback.OnBreakpointError(_BPError);
                    return(VSConstants.E_FAIL);
                }
                if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_CONDITION) != 0 &&
                    _bpRequestInfo.bpCondition.styleCondition == bpCondition.styleCondition &&
                    _bpRequestInfo.bpCondition.bstrCondition == bpCondition.bstrCondition)
                {
                    return(VSConstants.S_OK);  // this condition was already set
                }
                _bpRequestInfo.bpCondition = bpCondition;
                _bpRequestInfo.dwFields   |= enum_BPREQI_FIELDS.BPREQI_CONDITION;
                if (_bp != null)
                {
                    bp = _bp;
                }
            }
            if (bp != null)
            {
                _engine.DebuggedProcess.WorkerThread.RunOperation(() =>
                {
                    _engine.DebuggedProcess.AddInternalBreakAction(
                        () => bp.SetConditionAsync(bpCondition.bstrCondition, _engine.DebuggedProcess)
                        );
                });
            }
            return(VSConstants.S_OK);
        }
Beispiel #6
0
        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);
                        }
                    }
                }
            }
        }