Esempio n. 1
0
        /// <summary>
        /// Enumerates variables from the remote connection.
        /// </summary>
        /// <param name="runtime">The Visual Studio implementation of the runtime.</param>
        /// <param name="firstBatch">Tuple of enumeration id and first batch elements.</param>
        internal static IEnumerable <Variable> EnumerateVariables(VSClrRuntime runtime, Tuple <int, Tuple <ulong, int>[]> firstBatch)
        {
            VSDebuggerProxy proxy         = runtime.Proxy;
            uint            processId     = runtime.Process.Id;
            int             enumerationId = firstBatch.Item1;

            Tuple <ulong, int>[] batch = firstBatch.Item2;
            bool destroyed             = batch.Length == EnumerationBatchSize;

            try
            {
                while (batch.Length > 0)
                {
                    foreach (Tuple <ulong, int> tuple in batch)
                    {
                        IClrType clrType = runtime.GetClrType(tuple.Item2);

                        if (clrType != null)
                        {
                            ulong    address  = tuple.Item1;
                            CodeType codeType = runtime.Process.FromClrType(clrType);
                            Variable variable;

                            if (codeType.IsPointer)
                            {
                                variable = Variable.CreatePointerNoCast(codeType, address);
                            }
                            else
                            {
                                variable = Variable.CreateNoCast(codeType, address);
                            }

                            // TODO: Can we get already upcast address and clr type from the remote connection?
                            yield return(Variable.UpcastClrVariable(variable));
                        }
                    }

                    if (destroyed)
                    {
                        break;
                    }
                    batch     = proxy.GetVariableEnumeratorNextBatch(processId, enumerationId, EnumerationBatchSize);
                    destroyed = batch.Length == EnumerationBatchSize;
                }
            }
            finally
            {
                if (!destroyed)
                {
                    proxy.DisposeVariableEnumerator(processId, enumerationId);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClrMdThread"/> class.
        /// </summary>
        /// <param name="runtime">The Visual Studio runtime.</param>
        /// <param name="threadId">The thread system id.</param>
        /// <param name="isFinalizerThread">Is this finalizer thread.</param>
        /// <param name="appDomainAddress">The application domain address.</param>
        public VSClrThread(VSClrRuntime runtime, uint threadId, bool isFinalizerThread, ulong appDomainAddress)
        {
            VSRuntime           = runtime;
            SystemId            = threadId;
            IsFinalizerThread   = isFinalizerThread;
            clrStackFramesCache = SimpleCache.Create(() =>
            {
                Tuple <int, ulong, ulong, ulong>[] frames = Proxy.GetClrThreadFrames(Runtime.Process.Id, runtime.Id, SystemId);
                VSClrStackFrame[] clrFrames = new VSClrStackFrame[frames.Length];

                for (int i = 0; i < frames.Length; i++)
                {
                    clrFrames[i] = new VSClrStackFrame(this, frames[i].Item1, frames[i].Item2, frames[i].Item3, frames[i].Item4);
                }
                return(clrFrames);
            });
            stackTraceCache = SimpleCache.Create(() =>
            {
                Thread thread         = VSRuntime.Process.Threads.First(t => t.SystemId == SystemId);
                StackTrace stackTrace = new StackTrace(thread);
                uint frameNumber      = 0;

                stackTrace.Frames = clrStackFramesCache.Value.Select(f =>
                {
                    return(new StackFrame(stackTrace, new ThreadContext(f.InstructionPointer, f.StackPointer, ulong.MaxValue, null))
                    {
                        FrameNumber = frameNumber++,
                        InstructionOffset = f.InstructionPointer,
                        StackOffset = f.StackPointer,
                        FrameOffset = ulong.MaxValue,
                        ReturnOffset = ulong.MaxValue,
                        ClrStackFrame = f,
                    });
                }).ToArray();
                return(stackTrace);
            });
            appDomainCache           = SimpleCache.Create(() => Runtime.AppDomains.Single(a => a.Address == appDomainAddress));
            lastThrownExceptionCache = SimpleCache.Create(() =>
            {
                Tuple <ulong, int> tuple = Proxy.GetClrThreadLastException(Runtime.Process.Id, runtime.Id, SystemId);
                ulong address            = tuple.Item1;
                IClrType clrType         = runtime.GetClrType(tuple.Item2);

                if (clrType == null)
                {
                    return(null);
                }
                return(Variable.CreatePointer(runtime.Process.FromClrType(clrType), address));
            });
        }
Esempio n. 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VSClrType"/> class.
        /// </summary>
        /// <param name="runtime">The owning runtime.</param>
        /// <param name="id">The type identifier.</param>
        public VSClrType(VSClrRuntime runtime, int id)
        {
            Runtime     = runtime;
            Id          = id;
            moduleCache = SimpleCache.Create(() => Runtime.GetModule(Proxy.GetClrTypeModule(Runtime.Process.Id, id)));
            dataCache   = SimpleCache.Create(() =>
            {
                Tuple <int, int, int, int, int, int, string> tuple = Proxy.GetClrTypeSimpleData(Runtime.Process.Id, id);

                return(new SimpleData
                {
                    BaseSize = tuple.Item1,
                    BaseTypeId = tuple.Item2,
                    ComponentTypeId = tuple.Item3,
                    ElementSize = tuple.Item4,
                    ElementType = tuple.Item5,
                    HasSimpleValue = (tuple.Item6 & 1) != 0,
                    IsArray = (tuple.Item6 & 2) != 0,
                    IsEnum = (tuple.Item6 & 4) != 0,
                    IsObjectReference = (tuple.Item6 & 8) != 0,
                    IsPointer = (tuple.Item6 & 16) != 0,
                    IsPrimitive = (tuple.Item6 & 32) != 0,
                    IsString = (tuple.Item6 & 64) != 0,
                    IsValueClass = (tuple.Item6 & 128) != 0,
                    Name = tuple.Item7,
                });
            });
            fieldsCache = SimpleCache.Create(() =>
            {
                Tuple <string, int, int, int>[] fieldTuples = Proxy.GetClrTypeFields(Runtime.Process.Id, id);
                VSClrInstanceField[] fields = new VSClrInstanceField[fieldTuples.Length];

                for (int i = 0; i < fields.Length; i++)
                {
                    fields[i] = new VSClrInstanceField(fieldTuples[i].Item1, Runtime.GetClrType(fieldTuples[i].Item2), fieldTuples[i].Item3, fieldTuples[i].Item4);
                }
                return(fields);
            });
        }