public void HeapEnumerationWhileClearingCache() { // Simply test that we can enumerate the heap. using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrObject[] objects = heap.EnumerateObjects().ToArray(); Assert.NotEmpty(objects); int i = 0; foreach (ClrObject obj in heap.EnumerateObjects()) { Assert.Equal(objects[i].Address, obj.Address); Assert.Equal(objects[i].Type, obj.Type); if ((i % 8) == 0) { runtime.FlushCachedData(); } i++; } }
public Runtime(ITarget target, int id, ClrInfo clrInfo) { Target = target ?? throw new ArgumentNullException(nameof(target)); Id = id; _clrInfo = clrInfo ?? throw new ArgumentNullException(nameof(clrInfo)); RuntimeType = RuntimeType.Unknown; if (clrInfo.Flavor == ClrFlavor.Core) { RuntimeType = RuntimeType.NetCore; } else if (clrInfo.Flavor == ClrFlavor.Desktop) { RuntimeType = RuntimeType.Desktop; } RuntimeModule = target.Services.GetService <IModuleService>().GetModuleFromBaseAddress(clrInfo.ModuleInfo.ImageBase); ServiceProvider = new ServiceProvider(); ServiceProvider.AddService <ClrInfo>(clrInfo); ServiceProvider.AddServiceFactoryWithNoCaching <ClrRuntime>(() => CreateRuntime()); target.OnFlushEvent.Register(() => _clrRuntime?.FlushCachedData()); Trace.TraceInformation($"Created runtime #{id} {clrInfo.Flavor} {clrInfo}"); }
private static void ClearThreadProc() { while (true) { lock (_sync) { if (_runtimeForClearing != null) { _runtimeForClearing.FlushCachedData(); } } Thread.Sleep(500); } }
public void ModuleEqualityTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule[] oldModules = runtime.EnumerateModules().ToArray(); Assert.NotEmpty(oldModules); runtime.FlushCachedData(); ClrModule[] newModules = runtime.EnumerateModules().ToArray(); Assert.Equal(oldModules.Length, newModules.Length); for (int i = 0; i < newModules.Length; i++) { Assert.Equal(oldModules[i], newModules[i]); Assert.NotSame(oldModules[i], newModules[i]); } }
public void TypeEqualityTest() { // This test ensures that only one ClrType is created when we have a type loaded into two different AppDomains with two different // method tables. const string TypeName = "Foo"; using DataTarget dt = TestTargets.AppDomains.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrType[] types = (from obj in heap.EnumerateObjects() let t = heap.GetObjectType(obj.Address) where t.Name == TypeName orderby t.MethodTable select t).ToArray(); Assert.Equal(2, types.Length); Assert.NotSame(types[0], types[1]); ClrType[] typesFromModule = (from module in runtime.EnumerateModules() let name = Path.GetFileNameWithoutExtension(module.Name) where name.Equals("sharedlibrary", StringComparison.OrdinalIgnoreCase) let type = module.GetTypeByName(TypeName) select type).ToArray(); Assert.Equal(2, typesFromModule.Length); Assert.NotSame(types[0], types[1]); Assert.NotEqual(types[0], types[1]); if (dt.CacheOptions.CacheTypes) { Assert.Same(types[0], typesFromModule[0]); Assert.Same(types[1], typesFromModule[1]); } else { Assert.Equal(types[0], typesFromModule[0]); Assert.Equal(types[1], typesFromModule[1]); } // Get new types runtime.FlushCachedData(); ClrType[] newTypes = (from module in runtime.EnumerateModules() let name = Path.GetFileNameWithoutExtension(module.Name) where name.Equals("sharedlibrary", StringComparison.OrdinalIgnoreCase) let type = module.GetTypeByName(TypeName) select type).ToArray(); Assert.Equal(2, newTypes.Length); for (int i = 0; i < newTypes.Length; i++) { Assert.NotSame(typesFromModule[i], newTypes[i]); Assert.Equal(typesFromModule[i], newTypes[i]); } // Even though these are the same underlying type defined in sharedlibrary's metadata, // they have different MethodTables, Parent modules, and parent domains. These do not // compare as equal. Assert.NotEqual(typesFromModule[0], typesFromModule[1]); }
public void ClearCached() { _runtime.FlushCachedData(); }
public void EnsureFlushClearsData() { using DataTarget dt = TestTargets.AppDomains.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); var oldShared = runtime.SharedDomain; var oldSystem = runtime.SystemDomain; var oldDomains = runtime.AppDomains; var oldHeap = runtime.Heap; var oldModules = runtime.EnumerateModules().ToArray(); var oldObjects = oldHeap.EnumerateObjects().Take(20).ToArray(); var oldFields = oldObjects.SelectMany(o => o.Type.Fields).ToArray(); var oldStaticFields = oldObjects.SelectMany(o => o.Type.StaticFields).ToArray(); var oldMethods = oldObjects.SelectMany(o => o.Type.Methods).ToArray(); var oldThreads = runtime.Threads; // Ensure names are read and cached foreach (var obj in oldObjects) { _ = obj.Type.Name; foreach (var item in obj.Type.Methods) { _ = item.Name; } foreach (var item in obj.Type.Fields) { _ = item.Name; } foreach (var item in obj.Type.StaticFields) { _ = item.Name; } } foreach (var module in oldModules) { _ = module.Name; _ = module.FileName; _ = module.AssemblyName; } // Ensure we have some data to compare against Assert.NotEmpty(oldDomains); Assert.NotEmpty(oldModules); Assert.NotEmpty(oldObjects); Assert.NotEmpty(oldThreads); Assert.NotEmpty(oldFields); Assert.NotEmpty(oldStaticFields); Assert.NotEmpty(oldMethods); // Make sure we aren't regenerating this list every time. Assert.Same(oldDomains, runtime.AppDomains); // Clear all cached data. runtime.FlushCachedData(); CheckDomainNotSame(oldShared, runtime.SharedDomain); CheckDomainNotSame(oldSystem, runtime.SystemDomain); Assert.Equal(oldDomains.Count, runtime.AppDomains.Count); for (int i = 0; i < oldDomains.Count; i++) { CheckDomainNotSame(oldDomains[i], runtime.AppDomains[i]); } var newModules = runtime.EnumerateModules().ToArray(); for (int i = 0; i < oldModules.Length; i++) { CheckModuleNotSame(oldModules[i], newModules[i]); } ClrHeap newHeap = runtime.Heap; var newObjs = newHeap.EnumerateObjects().Take(20).ToArray(); Assert.Equal(oldObjects.Length, newObjs.Length); for (int i = 0; i < oldObjects.Length; i++) { Assert.Equal(oldObjects[i].Address, newObjs[i].Address); CheckTypeNotSame(oldObjects[i].Type, newObjs[i].Type); } var newThreads = runtime.Threads; Assert.Same(newThreads, runtime.Threads); Assert.Equal(oldThreads.Count, newThreads.Count); for (int i = 0; i < oldThreads.Count; i++) { Assert.Equal(oldThreads[i].OSThreadId, newThreads[i].OSThreadId); Assert.NotSame(oldThreads[i], newThreads[i]); } }