Example #1
0
        int IDebugProperty2.EnumChildren(enum_DEBUGPROP_INFO_FLAGS dwFields, uint dwRadix, ref Guid guidFilter, enum_DBG_ATTRIB_FLAGS dwAttribFilter, string pszNameFilter, uint dwTimeout, out IEnumDebugPropertyInfo2 ppEnum)
        {
            IEnumerable <DebugEvaluationResult> children = _children.Value;

            if (!RToolsSettings.Current.ShowDotPrefixedVariables)
            {
                children = children.Where(v => v.Name != null && !v.Name.StartsWith("."));
            }

            if (IsFrameEnvironment)
            {
                children = children.OrderBy(v => v.Name);
            }

            var infos = children.Select(v => new AD7Property(this, v).GetDebugPropertyInfo(dwRadix, dwFields));

            var valueResult = EvaluationResult as DebugValueEvaluationResult;

            if (valueResult != null && valueResult.HasAttributes == true)
            {
                string attrExpr   = Invariant($"base::attributes({valueResult.Expression})");
                var    attrResult = TaskExtensions.RunSynchronouslyOnUIThread(ct => StackFrame.StackFrame.EvaluateAsync(attrExpr, "attributes()", PrefetchedFields, ReprMaxLength, ct));
                if (!(attrResult is DebugErrorEvaluationResult))
                {
                    var attrInfo = new AD7Property(this, attrResult, isSynthetic: true).GetDebugPropertyInfo(dwRadix, dwFields);
                    infos = new[] { attrInfo }.Concat(infos);
                }
            }

            ppEnum = new AD7PropertyInfoEnum(infos.ToArray());
            return(VSConstants.S_OK);
        }
Example #2
0
        public AD7StackFrame(AD7Engine engine, DebugStackFrame stackFrame)
        {
            Engine     = engine;
            StackFrame = stackFrame;

            _property = Lazy.Create(() => new AD7Property(this, TaskExtensions.RunSynchronouslyOnUIThread(ct => StackFrame.GetEnvironmentAsync(cancellationToken: ct)), isFrameEnvironment: true));
        }
Example #3
0
        int IDebugExpression2.EvaluateSync(enum_EVALFLAGS dwFlags, uint dwTimeout, IDebugEventCallback2 pExprCallback, out IDebugProperty2 ppResult)
        {
            var res = TaskExtensions.RunSynchronouslyOnUIThread(ct => StackFrame.StackFrame.EvaluateAsync(_expression, AD7Property.PrefetchedFields, AD7Property.ReprMaxLength, ct));

            ppResult = new AD7Property(StackFrame, res);
            return(VSConstants.S_OK);
        }
Example #4
0
        private int Continue(IDebugThread2 pThread)
        {
            ThrowIfDisposed();

            if (_firstContinue)
            {
                _firstContinue = false;
            }
            else
            {
                // If _sentContinue is true, then this is a dummy Continue issued to notify the
                // debugger that user has explicitly entered something at the Browse prompt, and
                // we don't actually need to issue the command to R debugger.

                Func <CancellationToken, Task> continueMethod = null;
                lock (_browseLock) {
                    if (_sentContinue != true)
                    {
                        _sentContinue  = true;
                        continueMethod = ct => DebugSession.ContinueAsync(ct);
                    }
                }

                if (continueMethod != null)
                {
                    TaskExtensions.RunSynchronouslyOnUIThread(continueMethod);
                }
            }

            return(VSConstants.S_OK);
        }
Example #5
0
 private void ResetStackFrames()
 {
     _stackFrames = Lazy.Create(() =>
                                (IReadOnlyList <DebugStackFrame>)
                                TaskExtensions.RunSynchronouslyOnUIThread(ct => Engine.DebugSession.GetStackFramesAsync(ct))
                                .Reverse()
                                .ToArray());
 }
Example #6
0
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            ThrowIfDisposed();

            if (rgpPrograms.Length != 1)
            {
                throw new ArgumentException("Zero or more than one programs", "rgpPrograms");
            }

            _program = rgpPrograms[0] as RDebugPortSupplier.DebugProgram;
            if (_program == null)
            {
                throw new ArgumentException("rgpPrograms[0] must be an " + nameof(RDebugPortSupplier.DebugProgram), "rgpPrograms");
            }

            Marshal.ThrowExceptionForHR(_program.GetProgramId(out _programId));

            _events      = pCallback;
            DebugSession = TaskExtensions.RunSynchronouslyOnUIThread(ct => DebugSessionProvider.GetDebugSessionAsync(_program.Session, ct));
            MainThread   = new AD7Thread(this);
            IsConnected  = true;

            // Enable breakpoint instrumentation.
            TaskExtensions.RunSynchronouslyOnUIThread(ct => DebugSession.EnableBreakpointsAsync(true, ct));

            // Send notification after acquiring the session - we need it in case there were any breakpoints pending before
            // the attach, in which case we'll immediately get breakpoint creation requests as soon as we send these, and
            // we will need the session to process them.
            AD7EngineCreateEvent.Send(this);
            AD7ProgramCreateEvent.Send(this);
            Send(new AD7LoadCompleteEvent(), AD7LoadCompleteEvent.IID);

            // Register event handlers after notifying VS that debug engine has loaded. This order is important because
            // we may get a Browse event immediately, and we want to raise a breakpoint notification in response to that
            // to pause the debugger - but it will be ignored unless the engine has reported its creation.
            // Also, AfterRequest must be registered before Browse, so that we never get in a situation where we get
            // Browse but not AfterRequest that follows it because of a race between raising and registration.
            DebugSession.RSession.AfterRequest += RSession_AfterRequest;
            DebugSession.RSession.Disconnected += RSession_Disconnected;

            // If we're already at the Browse prompt, registering the handler will result in its immediate invocation.
            // We want to handle that fully before we process any following AfterRequest event to avoid concurrency issues
            // where we pause and never resume, so hold the lock while adding the handler.
            lock (_browseLock) {
                DebugSession.Browse += Session_Browse;
            }

            return(VSConstants.S_OK);
        }
Example #7
0
        int IDebugProperty3.SetValueAsStringWithError(string pszValue, uint dwRadix, uint dwTimeout, out string errorString)
        {
            errorString = null;

            // TODO: dwRadix
            var setResult = TaskExtensions.RunSynchronouslyOnUIThread(ct => EvaluationResult.SetValueAsync(pszValue, ct)) as DebugErrorEvaluationResult;

            if (setResult != null)
            {
                errorString = setResult.ErrorText;
                return(VSConstants.E_FAIL);
            }

            return(VSConstants.S_OK);
        }
Example #8
0
        private int SetState(enum_BP_STATE state)
        {
            if (_state == enum_BP_STATE.BPS_ENABLED)
            {
                if (state == enum_BP_STATE.BPS_DISABLED || state == enum_BP_STATE.BPS_DELETED)
                {
                    if (DebugBreakpoint != null)
                    {
                        DebugBreakpoint.BreakpointHit -= DebugBreakpoint_BreakpointHit;
                        if (Engine.IsConnected)
                        {
                            if (Engine.IsProgramDestroyed)
                            {
                                // If engine is shutting down, do not wait for the delete eval to complete, to avoid
                                // blocking debugger detach if a long-running operation is in progress. This way the
                                // engine can just report successful detach right away, and breakpoints are deleted
                                // later, but as soon as it's actually possible.
                                DebugBreakpoint.DeleteAsync()
                                .SilenceException <MessageTransportException>()
                                .SilenceException <RException>()
                                .DoNotWait();
                            }
                            else
                            {
                                TaskExtensions.RunSynchronouslyOnUIThread(ct => DebugBreakpoint.DeleteAsync(ct));
                            }
                        }
                    }
                }
            }
            else
            {
                if (state == enum_BP_STATE.BPS_ENABLED)
                {
                    if (Engine.IsProgramDestroyed)
                    {
                        // Do not allow enabling breakpoints when engine is shutting down.
                        return(VSConstants.E_ABORT);
                    }

                    DebugBreakpoint = TaskExtensions.RunSynchronouslyOnUIThread(ct => Engine.DebugSession.CreateBreakpointAsync(Location, ct));
                    DebugBreakpoint.BreakpointHit += DebugBreakpoint_BreakpointHit;
                }
            }

            _state = state;
            return(VSConstants.S_OK);
        }
Example #9
0
        private string CreateReprToString()
        {
            var ev = TaskExtensions.RunSynchronouslyOnUIThread(ct => EvaluationResult.EvaluateAsync(DebugEvaluationResultFields.Repr | DebugEvaluationResultFields.ReprToString, cancellationToken: ct));

            return((ev as DebugValueEvaluationResult)?.GetRepresentation().ToString);
        }
Example #10
0
 private IReadOnlyList <DebugEvaluationResult> CreateChildren()
 {
     return(TaskExtensions.RunSynchronouslyOnUIThread(ct => (EvaluationResult as DebugValueEvaluationResult)?.GetChildrenAsync(PrefetchedFields, ChildrenMaxLength, ReprMaxLength, ct))
            ?? new DebugEvaluationResult[0]);
 }