public void ComponentTypeEventuallyFilledTest() { // https://github.com/microsoft/clrmd/issues/108 // Ensure that a previously created type with a erroneous null ComponentType eventually // gets its ComponentType set. using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrType fooType = runtime.GetModule(ModuleName).GetTypeByName("Types"); ClrStaticField list = fooType.GetStaticFieldByName("s_list"); Assert.NotNull(list); ClrInstanceField itemsField = list.Type.GetFieldByName("_items"); ClrElementType elementType = itemsField.ElementType; ClrType componentType = itemsField.Type.ComponentType; // If this assert fails, remove the test. This value is null because currently CLR's // debugging layer doesn't tell us the component type of an array. If we eventually // fix that issue, we would return a non-null m_array.Type.ComponentType, causing // this test to fail but the underlying issue would be fixed. Assert.Null(componentType); ClrObject itemsObj = list.ReadObject(runtime.AppDomains.Single()).ReadObjectField("_items"); // Ensure we are looking at the same ClrType if (dt.CacheOptions.CacheTypes) { Assert.Same(itemsField.Type, itemsObj.Type); } else { Assert.Equal(itemsField.Type, itemsObj.Type); } // Assert that we eventually filled in ComponentType after we got a real object for the type Assert.NotNull(itemsObj.Type.ComponentType); }
/// <summary> /// Returns the list of runtimes in the target /// </summary> public IEnumerable <IRuntime> EnumerateRuntimes() { if (_runtimes is null) { _runtimes = new List <Runtime>(); if (_dataTarget is null) { _dataTarget = new DataTarget(new CustomDataTarget(this)) { BinaryLocator = null }; } if (_dataTarget is not null) { for (int i = 0; i < _dataTarget.ClrVersions.Length; i++) { _runtimes.Add(new Runtime(_target, i, _dataTarget.ClrVersions[i])); } } } return(_runtimes); }
private static ClrRuntime CreateRuntime(string dump, string dac) { // Create the data target. This tells us the versions of CLR loaded in the target process. DataTarget dataTarget = DataTarget.LoadCrashDump(dump); // Now check bitness of our program/target: bool isTarget64Bit = dataTarget.PointerSize == 8; if (Environment.Is64BitProcess != isTarget64Bit) { throw new Exception(string.Format("Architecture mismatch: Process is {0} but target is {1}", Environment.Is64BitProcess ? "64 bit" : "32 bit", isTarget64Bit ? "64 bit" : "32 bit")); } // Note I just take the first version of CLR in the process. You can loop over every loaded // CLR to handle the SxS case where both v2 and v4 are loaded in the process. var version = dataTarget.ClrVersions[0]; // Next, let's try to make sure we have the right Dac to load. CLRVersionInfo will actually // have the full path to the right dac if you are debugging the a version of CLR you have installed. // If they gave us a path (and not the actual filename of the dac), we'll try to handle that case too: if (dac != null && Directory.Exists(dac)) { dac = Path.Combine(dac, version.DacInfo.FileName); } else if (dac == null || !File.Exists(dac)) { dac = version.TryGetDacLocation(); } // Finally, check to see if the dac exists. If not, throw an exception. if (dac == null || !File.Exists(dac)) { throw new FileNotFoundException("Could not find the specified dac.", dac); } // Now that we have the DataTarget, the version of CLR, and the right dac, we create and return a // ClrRuntime instance. return(dataTarget.CreateRuntime(dac)); }
#pragma warning disable 618 private static JObject /*Task<JObject>*/ GetThreadTraces(DeadlockException de) { using var dataTarget = DataTarget.CreateSnapshotAndAttach(Process.GetCurrentProcess().Id); var version = dataTarget.ClrVersions[0]; var runtime = version.CreateRuntime(); var ret = new JObject(); var threads = App.RunningDispatchers.Values.Append(App.BaseDispatcher).Where(d => de.ThreadNames.Contains(d.Thread.Name)).Select(d => d.Thread).Append(PacketAnalyzer.AnalysisThread); foreach (var thread in threads) { if (thread?.Name == null) { continue; } var runtimeThread = runtime.Threads.FirstOrDefault(t => t.ManagedThreadId == thread.ManagedThreadId); if (runtimeThread != null) { ret[thread.Name] = GetStackTraceClrmd(runtimeThread); } //ret[thread.Name] = GetStackTrace(thread).ToString(); } //App.RunningDispatchers.Values.Append(App.BaseDispatcher).ToList().ForEach(d => //{ // var t = d.Thread; // t.Suspend(); // ret[t.Name] = new StackTrace(t, false).ToString(); // t.Resume(); //}); //if (PacketAnalyzer.AnalysisThread == null) return ret; //PacketAnalyzer.AnalysisThread.Suspend(); //ret["Analysis"] = new StackTrace(PacketAnalyzer.AnalysisThread, false).ToString(); //PacketAnalyzer.AnalysisThread.Resume(); return(ret); }
static void Main(string[] args) { // needs to run in docker: AttachToProcess is not supported on Darwin 19.4.0 int.TryParse(args[0], out var processId); Console.WriteLine("Attaching for PID: " + processId.ToString()); var suspendOnStart = false; Console.WriteLine("Hello World!"); DataTarget dataTarget = DataTarget.AttachToProcess(processId, suspendOnStart); if (dataTarget != null) { Console.WriteLine("Attached."); Console.WriteLine("Name: " + dataTarget.DataReader.DisplayName); Console.WriteLine("Arch: " + dataTarget.DataReader.Architecture.ToString()); var modules = dataTarget.DataReader.EnumerateModules(); foreach (var module in modules) { Console.WriteLine("file: " + module.FileName); } var clrVersions = dataTarget.ClrVersions; foreach (var version in clrVersions) { Console.WriteLine("dacPath: " + version.DacInfo.LocalDacPath); } // we have a live dac! (i think). var dac = new DacLibrary(dataTarget, clrVersions[0].DacInfo.LocalDacPath); var dacDebug = dac.DacPrivateInterface.QueryInterface(Guid.NewGuid()); } else { Console.WriteLine("Not attached."); } }
public void NoMethodCachingTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); dt.CacheOptions.CacheMethods = false; dt.CacheOptions.CacheMethodNames = StringCaching.None; using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod method = type.GetMethod("Bar"); Assert.NotEqual(0ul, method.MethodDesc); // Sanity test ClrMethod method2 = type.GetMethod("Bar"); Assert.Equal(method, method2); Assert.NotSame(method, method2); string signature1 = method.Signature; string signature2 = method2.Signature; Assert.NotNull(signature1); Assert.Equal(signature1, signature2); Assert.Equal(signature1, method.Signature); Assert.NotSame(signature1, method.Signature); Assert.NotSame(method2.Signature, method.Signature); // Ensure that we can swap this at runtime and that we get interned strings dt.CacheOptions.CacheMethodNames = StringCaching.Intern; Assert.NotNull(method.Signature); Assert.Same(method2.Signature, method.Signature); Assert.Same(method.Signature, string.Intern(method.Signature)); }
private static ClrRuntime CreateRuntime(string dump, string dac) { // Create the data target. This tells us the versions of CLR loaded in the target process. DataTarget dataTarget = DataTarget.LoadCrashDump(dump); // Now check bitness of our program/target: bool isTarget64Bit = dataTarget.PointerSize == 8; if (Environment.Is64BitProcess != isTarget64Bit) { throw new Exception(string.Format("Architecture mismatch: Process is {0} but target is {1}", Environment.Is64BitProcess ? "64 bit" : "32 bit", isTarget64Bit ? "64 bit" : "32 bit")); } // Note I just take the first version of CLR in the process. You can loop over every loaded // CLR to handle the SxS case where both v2 and v4 are loaded in the process. ClrInfo version = dataTarget.ClrVersions[0]; // Next, let's try to make sure we have the right Dac to load. Note we are doing this manually for // illustration. Simply calling version.CreateRuntime with no arguments does the same steps. if (dac != null && Directory.Exists(dac)) { dac = Path.Combine(dac, version.DacInfo.FileName); } else if (dac == null || !File.Exists(dac)) { dac = dataTarget.SymbolLocator.FindBinary(version.DacInfo); } // Finally, check to see if the dac exists. If not, throw an exception. if (dac == null || !File.Exists(dac)) { throw new FileNotFoundException("Could not find the specified dac.", dac); } // Now that we have the DataTarget, the version of CLR, and the right dac, we create and return a // ClrRuntime instance. return(version.CreateRuntime(dac)); }
public void TestTypeMapRoundTrip() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); int badTypes = 0; foreach (ClrModule module in runtime.EnumerateModules()) { foreach ((ulong mt, int token) in module.EnumerateTypeDefToMethodTableMap()) { Assert.NotEqual(0, token); Assert.True((token & 0x02000000) == 0x02000000); ClrType type = runtime.GetTypeByMethodTable(mt); if (type == null) { // We really want to Assert.NotNull(type), but it turns out that one type // (System.Runtime.Remoting.Proxies.__TransparentProxy) cannot be constructed because // GetMethodTableData returns null for it. This is an issue with the dac so we'll // simply count types that are null and assert there's only one badTypes++; continue; } Assert.NotNull(type); ClrType typeFromToken = module.ResolveToken(token); Assert.NotNull(typeFromToken); Assert.Same(type, typeFromToken); } } Assert.True(badTypes <= 1); }
ClrDac CreateCore(int pid, string clrPath, IClrDacDebugger clrDacDebugger) { DataTarget dataTarget = null; bool failed = true; try { // The timeout isn't used if Passive is used dataTarget = DataTarget.AttachToProcess(pid, 0, AttachFlag.Passive); var clrInfo = GetClrInfo(dataTarget, clrPath); if (clrInfo == null) { return(null); } // Use this overload to make sure it doesn't try to download the dac file which // will block this thread for several seconds or much longer. var clrRuntime = clrInfo.CreateRuntime(clrInfo.LocalMatchingDac); var clrDac = new ClrDacImpl(dataTarget, clrRuntime, clrDacDebugger); failed = false; return(clrDac); } catch (ClrDiagnosticsException) { return(null); } catch (IOException) { return(null); } catch (InvalidOperationException) { return(null); } finally { if (failed) { dataTarget?.Dispose(); } } }
private DiagnosticAnalyzer(DataTarget dataTarget, bool cacheObjects) { _dataTarget = dataTarget; CacheAllObjects = cacheObjects; //_dataTarget.BinaryLocator.FindBinary() if (_dataTarget.ClrVersions.Length == 0) { throw new Exception("No compatible CLR has been found on this machine"); } if (_dataTarget.ClrVersions.Length > 1) { Debug.WriteLine("Multiple compatible CLR have been found on this machine, picking the first of the following list"); foreach (var version in _dataTarget.ClrVersions) { var dacFilename = version.DacInfo.PlatformSpecificFileName; var moduleInfo = version.ModuleInfo; Debug.WriteLine("CLR Version: " + version.Version); Debug.WriteLine("Filesize: {0:X}", moduleInfo.IndexFileSize); Debug.WriteLine("Timestamp: {0:X}", moduleInfo.IndexTimeStamp); Debug.WriteLine("Dac File: {0}", dacFilename); Debug.WriteLine(""); } } _clrInfo = _dataTarget.ClrVersions[0]; if (_clrInfo.DacInfo.LocalDacPath == null) { throw new Exception($"The runtime used in the dump is {_clrInfo.DacInfo.Version} and cannot be found on this installation"); } _clrLocation = new FileInfo(_clrInfo.DacInfo.LocalDacPath); _clrRuntime = _clrInfo.CreateRuntime(); _dacInfo = _clrInfo.DacInfo; PrepareGCRootCache(); }
public void Decompile(Stream assemblyStream, TextWriter codeWriter) { var currentSetup = AppDomain.CurrentDomain.SetupInformation; using (var dataTarget = DataTarget.AttachToProcess(CurrentProcess.Id, UInt32.MaxValue, AttachFlag.Passive)) using (var context = AppDomainContext.Create(new AppDomainSetup { ApplicationBase = currentSetup.ApplicationBase, PrivateBinPath = currentSetup.PrivateBinPath })) { context.LoadAssembly(LoadMethod.LoadFrom, Assembly.GetExecutingAssembly().GetAssemblyFile().FullName); var results = RemoteFunc.Invoke(context.Domain, assemblyStream, Remote.GetCompiledMethods); var currentMethodAddressRef = new Reference <ulong>(); var runtime = dataTarget.ClrVersions.Single().CreateRuntime(); var translator = new IntelTranslator { SymbolResolver = (Instruction instruction, long addr, ref long offset) => ResolveSymbol(runtime, instruction, addr, currentMethodAddressRef.Value) }; codeWriter.WriteLine("; This is an experimental implementation."); codeWriter.WriteLine("; Please report any bugs to https://github.com/ashmind/TryRoslyn/issues."); codeWriter.WriteLine(); foreach (var result in results) { var methodHandle = (ulong)result.Handle.ToInt64(); var method = runtime.GetMethodByHandle(methodHandle); if (method == null) { codeWriter.WriteLine(" ; Method with handle 0x{0:X} was somehow not found by CLRMD.", methodHandle); codeWriter.WriteLine(" ; See https://github.com/ashmind/TryRoslyn/issues/84."); continue; } DisassembleAndWrite(method, result.Message, translator, currentMethodAddressRef, codeWriter); codeWriter.WriteLine(); } } }
[WindowsFact] // ModuleInfo.Version only supports native modules at the moment public void FileVersionInfoVersionTest() { bool found = false; // Make sure we never return different values for the version using DataTarget dt = TestTargets.Types.LoadFullDump(); foreach (ModuleInfo module in dt.EnumerateModules()) { if (!module.IsManaged) { continue; } PEImage img = module.GetPEImage(); Assert.NotNull(img); FileVersionInfo fileVersionInfo = img.GetFileVersionInfo(); if (fileVersionInfo != null) { VersionInfo moduleVersion = module.Version; Assert.Equal(moduleVersion, fileVersionInfo.VersionInfo); found = true; } if (Path.GetFileNameWithoutExtension(module.FileName).Equals("types", StringComparison.OrdinalIgnoreCase)) { Assert.Equal("1.2.3.4", fileVersionInfo.FileVersion); Assert.Equal("1.2.3.4", fileVersionInfo.VersionInfo.ToString()); Assert.Equal("1.2.3.4", fileVersionInfo.ToString()); Assert.Equal(1, fileVersionInfo.VersionInfo.Major); Assert.Equal(2, fileVersionInfo.VersionInfo.Minor); Assert.Equal(3, fileVersionInfo.VersionInfo.Revision); Assert.Equal(4, fileVersionInfo.VersionInfo.Patch); } } Assert.True(found, "Did not find any modules with non-null GetFileVersionInfo to compare"); }
public void PdbSourceLineTest() { using (DataTarget dt = TestTargets.NestedException.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrThread thread = runtime.GetMainThread(); HashSet <int> sourceLines = new HashSet <int>(); using (PdbReader reader = new PdbReader(TestTargets.NestedException.Pdb)) { Assert.Equal(TestTargets.NestedException.Source, reader.Sources.Single().Name, true); IEnumerable <PdbFunction> functions = from frame in thread.StackTrace where frame.Kind != ClrStackFrameType.Runtime select reader.GetFunctionFromToken(frame.Method.MetadataToken); foreach (PdbFunction function in functions) { PdbSequencePointCollection sourceFile = function.SequencePoints.Single(); foreach (int line in sourceFile.Lines.Select(l => l.LineBegin)) { sourceLines.Add(line); } } } int curr = 0; foreach (string line in File.ReadLines(TestTargets.NestedException.Source)) { curr++; if (line.Contains("/* seq */")) { Assert.Contains(curr, sourceLines); } } } }
static void Main(string[] args) { //Console.Write("Введите PID процесса : "); //var pidStr = Console.ReadLine(); //if (!int.TryParse(pidStr, out var pid)) //{ // Console.WriteLine("Не валидный PID."); //} var startProcess = new ProcessStartInfo( "C:/Repos/ModulBank-CRM/Web Services/CrmIntegrations/AsyncService/AsyncService/bin/Ass/Modulbank.Crm.AsyncService.exe"); startProcess.CreateNoWindow = true; //startProcess.WindowStyle = ProcessWindowStyle.Hidden; var targetProcess = Process.Start(startProcess); var pid = targetProcess.Id; uint timeout = 10000; try { using (var target = DataTarget.AttachToProcess(pid, timeout, AttachFlag.Invasive)) { PrintDumpInfo(target, Console.WriteLine); } targetProcess.Kill(); } catch (Exception exc) { Console.WriteLine($"Не удалось прицепиться к файлу : {exc.ToString()}."); } Console.WriteLine("Введите любое значение для выхода."); Console.ReadLine(); }
public void ObjectSetAddRemove() { using (DataTarget dataTarget = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ObjectSet hash = new ObjectSet(heap); foreach (ulong obj in heap.EnumerateObjectAddresses()) { Assert.IsFalse(hash.Contains(obj)); hash.Add(obj); Assert.IsTrue(hash.Contains(obj)); } foreach (ulong obj in heap.EnumerateObjectAddresses()) { Assert.IsTrue(hash.Contains(obj)); hash.Remove(obj); Assert.IsFalse(hash.Contains(obj)); } } }
public void EnumerateAllPathshCancel() { using (DataTarget dataTarget = TestTargets.GCRoot.LoadFullDump()) { ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; heap.StackwalkPolicy = ClrRootStackwalkPolicy.SkipStack; GCRoot gcroot = new GCRoot(runtime.Heap); CancellationTokenSource cancelSource = new CancellationTokenSource(); cancelSource.Cancel(); GetKnownSourceAndTarget(runtime.Heap, out ulong source, out ulong target); try { gcroot.EnumerateAllPaths(source, target, false, cancelSource.Token).ToArray(); Assert.Fail("Should have been cancelled!"); } catch (OperationCanceledException) { } } }
public void InstanceFieldProperties() { using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrType foo = runtime.GetModule("sharedlibrary.dll").GetTypeByName("Foo"); Assert.NotNull(foo); CheckField(foo, "i", ClrElementType.Int32, "System.Int32", 4); CheckField(foo, "s", ClrElementType.String, "System.String", IntPtr.Size); CheckField(foo, "b", ClrElementType.Boolean, "System.Boolean", 1); CheckField(foo, "f", ClrElementType.Float, "System.Single", 4); CheckField(foo, "d", ClrElementType.Double, "System.Double", 8); CheckField(foo, "o", ClrElementType.Object, "System.Object", IntPtr.Size); // Fails due to: https://github.com/Microsoft/clrmd/issues/101 //CheckField(foo, "st", ClrElementType.Struct, "Struct", 4); } }
public void PrevObject() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; foreach (ClrSegment seg in heap.Segments) { if (seg.Length == 0) { continue; } ClrObject prev = heap.GetObject(seg.FirstObjectAddress); Assert.Equal(0ul, seg.GetPreviousObjectAddress(prev)); foreach (ClrObject curr in seg.EnumerateObjects().Skip(1)) { Assert.Equal(prev.Address, seg.GetPreviousObjectAddress(curr)); prev = curr; } } }
public void EnsureEnumerationStability() { // I made some changes to v4.5 handle enumeration to enumerate handles out faster. // This test makes sure I have a stable enumeration. using DataTarget dt = TestTargets.GCHandles.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); List <ClrHandle> handles = new List <ClrHandle>(runtime.EnumerateHandles()); int i = 0; foreach (ClrHandle hnd in runtime.EnumerateHandles()) { Assert.Equal(handles[i].Address, hnd.Address); Assert.Equal(handles[i].Object, hnd.Object); Assert.Equal(handles[i].HandleKind, hnd.HandleKind); i++; } // We create at least this many handles in the test, plus the runtime uses some. Assert.True(handles.Count > 4); }
public void EnumerateDelegateTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule typesModule = runtime.GetModule(TypeTests.ModuleName); ClrType Types = typesModule.GetTypeByName("Types"); ClrDelegate TestDelegate = Types.GetStaticFieldByName("TestDelegate").ReadObject(runtime.AppDomains.Single()).AsDelegate(); ClrDelegateTarget[] methods = TestDelegate.EnumerateDelegateTargets().ToArray(); Assert.Single(methods); CompareToInner(Types, TestDelegate, methods[0]); ClrDelegate TestEvent = Types.GetStaticFieldByName("TestEvent").ReadObject(runtime.AppDomains.Single()).AsDelegate(); methods = TestEvent.EnumerateDelegateTargets().ToArray(); Assert.Equal(2, methods.Length); CompareToInner(Types, TestEvent, methods[0]); CompareToInstanceMethod(Types, TestEvent, methods[1]); }
public RuntimeService(ITarget target) { _target = target; target.OnFlushEvent += (object sender, EventArgs e) => { if (_runtimes != null) { if (_runtimes.Count > 0) { foreach (Runtime runtime in _runtimes) { runtime.Flush(); } } else { // If there are no runtimes, try find them again when the target stops _runtimes = null; _dataTarget?.Dispose(); _dataTarget = null; } } }; }
public void PdbEqualityTest() { // Ensure all methods in our source file is in the pdb. using DataTarget dt = TestTargets.NestedException.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); PdbInfo[] allPdbs = runtime.EnumerateModules().Select(m => m.Pdb).Where(pdb => pdb != null).ToArray(); Assert.True(allPdbs.Length > 1); for (int i = 0; i < allPdbs.Length; i++) { Assert.NotNull(allPdbs[i]); Assert.True(allPdbs[i].Equals(allPdbs[i])); for (int j = i + 1; j < allPdbs.Length; j++) { if (allPdbs[i].Path != allPdbs[j].Path) { Assert.False(allPdbs[i].Equals(allPdbs[j])); Assert.False(allPdbs[j].Equals(allPdbs[i])); } } } }
public static IEnumerable <MEMORY_BASIC_INFORMATION64> EnumerateVMRegions(this DataTarget target) { var dataSpaces = (IDebugDataSpaces4)target.DebuggerInterface; ulong maxAddress = Environment.Is64BitProcess ? uint.MaxValue : ulong.MaxValue; for (ulong address = 0; address < maxAddress;) { MEMORY_BASIC_INFORMATION64 memInfo; if (0 != dataSpaces.QueryVirtual(address, out memInfo)) { break; } if (memInfo.RegionSize == 0) { break; } yield return(memInfo); address += memInfo.RegionSize; } }
public void Show() { DataTarget = Spheris.Billing.Data.BillingDataFactory.NewInstance().CreateInvoiceGroupRepository(); Specialists = DataTarget.GetSpecialists(); BillingSpecialist allSpecialists = new Spheris.Billing.Core.Domain.BillingSpecialist("*", 0); Specialists.Insert(0, allSpecialists); SelectedSpecialist = allSpecialists; DeliveryMethods = DataTarget.GetDeliveryMethods(); DeliveryMethod allDeliverys = new DeliveryMethod("*", "*"); DeliveryMethods.Insert(0, allDeliverys); SelectedDeliveryMethod = allDeliverys; //ViewCore.Show(); OnPropertyChanged("IsExpanded"); OnPropertyChanged("IGroups"); OnPropertyChanged("DeliveryMethods"); OnPropertyChanged("Specialists"); }
public void MinidumpCallstackTest() { using DataTarget dt = TestTargets.NestedException.LoadMiniDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrThread thread = runtime.GetMainThread(); string[] frames = IntPtr.Size == 8 ? new[] { "Inner", "Inner", "Middle", "Outer", "Main" } : new[] { "Inner", "Middle", "Outer", "Main" }; int i = 0; foreach (ClrStackFrame frame in thread.EnumerateStackTrace()) { if (frame.Kind == ClrStackFrameKind.ManagedMethod) { Assert.NotEqual(0ul, frame.InstructionPointer); Assert.NotEqual(0ul, frame.StackPointer); Assert.NotNull(frame.Method); Assert.NotNull(frame.Method.Type); Assert.NotNull(frame.Method.Type.Module); Assert.Equal(frames[i++], frame.Method.Name); } } }
public void ComponentType() { // 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; foreach (ClrObject obj in heap.EnumerateObjects()) { ClrType type = obj.Type; Assert.NotNull(type); if (type.IsArray || type.IsPointer) { Assert.NotNull(type.ComponentType); } else { Assert.Null(type.ComponentType); } } }
public void IntegerObjectClrType() { using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrStaticField field = runtime.GetModule("types.exe").GetTypeByName("Types").GetStaticFieldByName("s_i"); ulong addr = (ulong)field.GetValue(runtime.AppDomains.Single()); ClrType type = heap.GetObjectType(addr); Assert.True(type.IsPrimitive); Assert.False(type.IsObjectReference); Assert.False(type.IsValueClass); object value = type.GetValue(addr); Assert.Equal("42", value.ToString()); Assert.IsType <int>(value); Assert.Equal(42, (int)value); Assert.Contains(addr, heap.EnumerateObjectAddresses()); } }
public RuntimeService(ITarget target) { _target = target; // TODO - mikem 4/30/21 - remove when dbgeng services doesn't take so long looking up exports (attempts to load PDBs). _exportReaderEnabled = target.Host.HostType != HostType.DbgEng || Environment.GetEnvironmentVariable("DOTNET_ENABLE_SOS_SINGLEFILE") == "1"; _onFlushEvent = target.OnFlushEvent.Register(() => { if (_runtimes is not null && _runtimes.Count == 0) { // If there are no runtimes, try find them again when the target stops _runtimes = null; _dataTarget?.Dispose(); _dataTarget = null; } }); // Can't make RuntimeService IDisposable directly because _dataTarget.Dispose() disposes the IDataReader // passed which is this RuntimeService instance which would call _dataTarget.Dispose again and causing a // stack overflow. target.OnDestroyEvent.Register(() => { _dataTarget?.Dispose(); _dataTarget = null; _onFlushEvent.Dispose(); }); }
private static ClrRuntime CreateRuntime(int pid) { // Create the data target. This tells us the versions of CLR loaded in the target process. DataTarget dataTarget = DataTarget.AttachToProcess(pid, 60000, AttachFlag.Passive); dataTarget.SymbolLocator.SymbolPath = Environment.GetEnvironmentVariable("_NT_SYMBOL_PATH"); // Now check bitness of our program/target: bool isTarget64Bit = dataTarget.PointerSize == 8; if (Environment.Is64BitProcess != isTarget64Bit) { throw new Exception(string.Format("Architecture mismatch: Process is {0} but target is {1}", Environment.Is64BitProcess ? "64 bit" : "32 bit", isTarget64Bit ? "64 bit" : "32 bit")); } // Note I just take the first version of CLR in the process. You can loop over every loaded // CLR to handle the SxS case where both v2 and v4 are loaded in the process. ClrInfo version = dataTarget.ClrVersions[0]; // Now that we have the DataTarget, the version of CLR, and the right dac, we create and return a // ClrRuntime instance. return(version.CreateRuntime()); }
public void GCStaticRoots() { using DataTarget dataTarget = TestTargets.GCRoot.LoadFullDump(); ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; heap.StackwalkPolicy = ClrRootStackwalkPolicy.SkipStack; GCRoot gcroot = new GCRoot(runtime.Heap); gcroot.ClearCache(); Assert.False(gcroot.IsFullyCached); GCStaticRootsImpl(gcroot); gcroot.BuildCache(CancellationToken.None); gcroot.AllowParallelSearch = false; Assert.True(gcroot.IsFullyCached); GCStaticRootsImpl(gcroot); gcroot.AllowParallelSearch = true; Assert.True(gcroot.IsFullyCached); GCStaticRootsImpl(gcroot); }
private ulong GetWin32HeapSize(DataTarget target) { // TODO Find the ProcessHeaps pointer in the PEB, and the NumberOfHeaps field. // This is an array of _HEAP structure pointers. Each _HEAP structure has // a field called Counters of type HEAP_COUNTERS (is that so on older OS // versions as well?), which has information about the reserve and commit // size of that heap. This isn't accurate to the level of busy/free blocks, // but should be a reasonable estimate of which part of memory is used for // the Win32 heap. // To find the PEB, use IDebugSystemObjects::GetCurrentProcessPeb(). return 0; }
private ulong GetStacksSize(DataTarget target) { // Find all the TEBs and then sum StackBase - StackLimit for all of them. // This gives us the committed size for each thread, but we don't have the // reserved size (which is the actual address space consumed). Theoretically, // we could get it from enumerating the memory region adjacent to the committed // pages and the guard page that follows. Also, for WoW64 threads, we are only // reporting the x86 stack (the x64 stack doesn't live in the 4GB address space // anyway, so it's not that relevant). IDebugSystemObjects sysObjects = (IDebugSystemObjects)target.DebuggerInterface; uint numThreads; HR.Verify(sysObjects.GetNumberThreads(out numThreads)); ulong totalCommit = 0; for (uint i = 0; i < numThreads; ++i) { HR.Verify(sysObjects.SetCurrentThreadId(i)); ulong tebAddress; HR.Verify(sysObjects.GetCurrentThreadTeb(out tebAddress)); int read; byte[] teb = new byte[IntPtr.Size * 3]; // ExceptionList, StackBase, StackLimit if (target.ReadProcessMemory(tebAddress, teb, teb.Length, out read) && read == teb.Length) { ulong stackBase = AddressFromBytes(teb, IntPtr.Size); ulong stackLimit = AddressFromBytes(teb, IntPtr.Size * 2); totalCommit = stackBase - stackLimit; } } return totalCommit; }