예제 #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ClrMdHeap"/> class.
 /// </summary>
 /// <param name="runtime">The runtime.</param>
 public VSClrHeap(VSClrRuntime runtime)
 {
     VSRuntime           = runtime;
     canWalkHeapCache    = SimpleCache.Create(() => Proxy.GetClrHeapCanWalkHeap(VSRuntime.Process.Id, VSRuntime.Id));
     totalHeapSizeCache  = SimpleCache.Create(() => Proxy.GetClrHeapTotalHeapSize(VSRuntime.Process.Id, VSRuntime.Id));
     typesByAddressCache = new DictionaryCache <ulong, VSClrType>((a) => default(VSClrType));
 }
예제 #2
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);
                }
            }
        }
예제 #3
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));
            });
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VSClrAppDomain" /> class.
        /// </summary>
        /// <param name="runtime">The runtime.</param>
        /// <param name="id">The application domain identifier.</param>
        /// <param name="address">The application domain address.</param>
        /// <param name="applicationBase">The application domain base directory.</param>
        /// <param name="configurationFile">The configuration file used for application domain.</param>
        public VSClrAppDomain(VSClrRuntime runtime, int id, string name, ulong address, string applicationBase, string configurationFile)
        {
            VSRuntime         = runtime;
            Id                = id;
            Name              = name;
            Address           = address;
            ApplicationBase   = applicationBase;
            ConfigurationFile = configurationFile;
            modulesCache      = SimpleCache.Create(() =>
            {
                ulong[] moduleAddresses = VSRuntime.Proxy.GetClrAppDomainModules(VSRuntime.Process.Id, VSRuntime.Id, Id);
                VSClrModule[] modules   = new VSClrModule[moduleAddresses.Length];

                for (int i = 0; i < modules.Length; i++)
                {
                    modules[i] = VSRuntime.GetModule(moduleAddresses[i]);
                }
                return(modules);
            });
        }
예제 #5
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);
            });
        }
예제 #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VSClrModule"/> class.
 /// </summary>
 /// <param name="runtime">The owning runtime.</param>
 /// <param name="imageBase">The module image base.</param>
 public VSClrModule(VSClrRuntime runtime, ulong imageBase)
 {
     Runtime     = runtime;
     ImageBase   = imageBase;
     moduleCache = SimpleCache.Create(() => Runtime.Process.Modules.FirstOrDefault(m => m.Address == ImageBase));
 }