/// <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)); }
/// <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); } } }
/// <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)); }); }
/// <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); }); }
/// <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); }); }
/// <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)); }