private void EnsureInitialized([NotNull] ClrRuntime runtime)
        {
            if (initialized)
            {
                return;
            }

            try
            {
                ClrHeap heap = runtime.GetHeap();
                enumeratedTypes = new List <ClrType>();
                foreach (string typename in EnumeratedTypesNames)
                {
                    if (string.IsNullOrEmpty(typename))
                    {
                        continue;
                    }

                    ClrType tmp = heap.GetTypeByName(typename);
                    if (tmp == null)
                    {
                        Trace.TraceWarning("{0} type was not found in runtime.", typename);
                        continue;
                    }

                    enumeratedTypes.Add(tmp);
                }
            }
            finally
            {
                initialized = true;
            }
        }
Example #2
0
        public void ArrayReferenceEnumeration()
        {
            using (DataTarget dt = TestTargets.Types.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
                ClrHeap    heap    = runtime.Heap;

                ClrAppDomain domain = runtime.AppDomains.Single();

                ClrModule typesModule = runtime.GetModule("types.exe");
                ClrType   type        = heap.GetTypeByName("Types");


                ulong s_array = (ulong)type.GetStaticFieldByName("s_array").GetValue(domain);
                ulong s_one   = (ulong)type.GetStaticFieldByName("s_one").GetValue(domain);
                ulong s_two   = (ulong)type.GetStaticFieldByName("s_two").GetValue(domain);
                ulong s_three = (ulong)type.GetStaticFieldByName("s_three").GetValue(domain);

                ClrType arrayType = heap.GetObjectType(s_array);

                List <ulong> objs = new List <ulong>();
                arrayType.EnumerateRefsOfObject(s_array, (obj, offs) => objs.Add(obj));

                // We do not guarantee the order in which these are enumerated.
                Assert.Equal(3, objs.Count);
                Assert.Contains(s_one, objs);
                Assert.Contains(s_two, objs);
                Assert.Contains(s_three, objs);
            }
        }
Example #3
0
        public void ArrayOffsetsTest()
        {
            using (DataTarget dt = TestTargets.Types.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
                ClrHeap    heap    = runtime.Heap;

                ClrAppDomain domain = runtime.AppDomains.Single();

                ClrModule typesModule = runtime.GetModule("types.exe");
                ClrType   type        = heap.GetTypeByName("Types");

                ulong s_array = (ulong)type.GetStaticFieldByName("s_array").GetValue(domain);
                ulong s_one   = (ulong)type.GetStaticFieldByName("s_one").GetValue(domain);
                ulong s_two   = (ulong)type.GetStaticFieldByName("s_two").GetValue(domain);
                ulong s_three = (ulong)type.GetStaticFieldByName("s_three").GetValue(domain);

                ulong[] expected = new ulong[] { s_one, s_two, s_three };

                ClrType arrayType = heap.GetObjectType(s_array);

                for (int i = 0; i < expected.Length; i++)
                {
                    Assert.Equal(expected[i], (ulong)arrayType.GetArrayElementValue(s_array, i));

                    ulong address = arrayType.GetArrayElementAddress(s_array, i);
                    ulong value   = dt.DataReader.ReadPointerUnsafe(address);

                    Assert.NotEqual(0ul, address);
                    Assert.Equal(expected[i], value);
                }
            }
        }
Example #4
0
        private Dictionary <int, string> GetManagedThreadNames(ClrHeap heap)
        {
            var result = new Dictionary <int, string>();

            if (!heap.CanWalkHeap)
            {
                return(result);
            }

            var threadObjects = from obj in heap.EnumerateObjectAddresses()
                                let type = heap.GetObjectType(obj)
                                           where type != null && type.Name == "System.Threading.Thread"
                                           select obj;
            var threadType     = heap.GetTypeByName("System.Threading.Thread");
            var nameField      = threadType.GetFieldByName("m_Name");
            var managedIdField = threadType.GetFieldByName("m_ManagedThreadId");

            foreach (var threadObject in threadObjects)
            {
                string name = (string)nameField.GetValue(threadObject);
                int    id   = (int)managedIdField.GetValue(threadObject);
                result.Add(id, name);
            }

            return(result);
        }
        private DepPropertiesProvider(ulong objAddress, ClrHeap heap)
        {
            _targetObject = heap.GetInstance(objAddress);

            _effectiveValues = _targetObject.AsDynamic._effectiveValues;

            _depPropertyType = heap.GetTypeByName(DependencyPropertyTypeName);
        }
        public StaticField(ClrRuntime runtime, string typee, string name)
        {
            Domain = runtime.AppDomains.First();
            ClrHeap heap = runtime.GetHeap();
            ClrType type = heap.GetTypeByName(typee);

            Field = type.GetStaticFieldByName(name);
            Heap  = runtime.GetHeap();
        }
        private void InitSearchedType(ClrHeap heap)
        {
            this._searchedType = heap.GetTypeByName(this.searchedTypeName);

            Assert.Required(_searchedType, $"{searchedTypeName} was not found by name in the heap");

            this._typeIndex = this._searchedType.MetadataToken;

            searchedTypeSet = true;
        }
Example #8
0
        private ClrObject FindFirstInstanceOfType(ClrHeap heap, string typeName)
        {
            var type = heap.GetTypeByName(typeName);

            if (type is null)
            {
                throw new InvalidOperationException($"Could not find {typeName} in {TestTarget.Source} source.");
            }

            return(new ClrObject(heap.GetObjectsOfType(typeName).First(), type));
        }
Example #9
0
        public void ArrayLengthTest()
        {
            using (DataTarget dt = TestTargets.Types.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
                ClrHeap    heap    = runtime.Heap;

                ClrAppDomain domain = runtime.AppDomains.Single();

                ClrModule typesModule = runtime.GetModule("types.exe");
                ClrType   type        = heap.GetTypeByName("Types");

                ulong   s_array   = (ulong)type.GetStaticFieldByName("s_array").GetValue(domain);
                ClrType arrayType = heap.GetObjectType(s_array);

                Assert.Equal(3, arrayType.GetArrayLength(s_array));
            }
        }
        /// <summary>
        /// Gets the static field value.
        /// <para> WARN - resolves value for single domain only.</para>
        /// </summary>
        /// <param name="runtime">The runtime.</param>
        /// <param name="typeName">Name of the type.</param>
        /// <param name="fieldName">Name of the field.</param>
        /// <returns></returns>
        /// <exception cref="ClrTypeNotFound"></exception>
        public static ClrObject GetStaticFldValue(this ClrRuntime runtime, [NotNull] string typeName,
                                                  [NotNull] string fieldName)
        {
            Assert.ArgumentNotNullOrEmpty(typeName, "typeName");
            Assert.ArgumentNotNullOrEmpty(fieldName, "fieldName");
            ClrHeap heap = runtime.GetHeap();

            Assert.ResultNotNull(heap, "Could not fetch heap from runtime");

            ClrType type = heap.GetTypeByName(typeName);

            if (type == null)
            {
                throw new ClrTypeNotFound(typeName);
            }

            return(runtime.GetStaticFldValue(type, fieldName));
        }
Example #11
0
        public ClrDriver(ClrRuntime runtime)
        {
            (this.runtime, heap, domain) = (runtime, runtime.Heap, runtime.AppDomains[0]);

            typeObject          = heap.GetTypeByName("System.Object");
            typeDelegate        = heap.GetTypeByName("System.Delegate");
            fieldDelegateTarget = typeDelegate.GetFieldByName("_target");

            typeTask = heap.GetTypeByName("System.Threading.Tasks.Task");
            if (typeTask.BaseType.Name == "System.Threading.Tasks.Task")
            {
                typeTask = typeTask.BaseType;
            }
            fieldTaskAction             = typeTask.GetFieldByName("m_action");
            fieldTaskScheduler          = typeTask.GetFieldByName("m_taskScheduler");
            fieldTaskContinuationObject = typeTask.GetFieldByName("m_continuationObject");

            typeDelayPromise = heap.GetTypeByName("System.Threading.Tasks.Task+DelayPromise");
            typeQueueUserWorkItemCallback = heap.GetTypeByName("System.Threading.QueueUserWorkItemCallback");
            fieldCallback    = typeQueueUserWorkItemCallback.GetFieldByName("callback");
            typeWaitCallback = heap.GetTypeByName("System.Threading.WaitCallback");
        }
Example #12
0
 public IEnumerable <ValuePointer> AllValuesOfType(params string[] typeNames)
 {
     return(AllValuesOfType(from tn in typeNames select Heap.GetTypeByName(tn)));
 }
Example #13
0
        private Dictionary<int, string> GetManagedThreadNames(ClrHeap heap)
        {
            var result = new Dictionary<int, string>();
            if (!heap.CanWalkHeap)
                return result;

            var threadObjects = from obj in heap.EnumerateObjectAddresses()
                                let type = heap.GetObjectType(obj)
                                where type != null && type.Name == "System.Threading.Thread"
                                select obj;
            var threadType = heap.GetTypeByName("System.Threading.Thread");
            var nameField = threadType.GetFieldByName("m_Name");
            var managedIdField = threadType.GetFieldByName("m_ManagedThreadId");

            foreach (var threadObject in threadObjects)
            {
                string name = (string)nameField.GetValue(threadObject);
                int id = (int)managedIdField.GetValue(threadObject);
                result.Add(id, name);
            }

            return result;
        }
Example #14
0
 /// <summary>
 ///     Looks up a type by name.
 /// </summary>
 /// <param name="name">The name of the type.</param>
 /// <returns>
 ///     The ClrType matching 'name', null if the type was not found, and undefined if more than one
 ///     type shares the same name.
 /// </returns>
 /// <inheritdoc />
 public IClrType GetTypeByName(string name) => Converter.Convert(Heap.GetTypeByName(name));
Example #15
0
        // Sample based on https://github.com/Microsoft/dotnetsamples/blob/master/Microsoft.Diagnostics.Runtime/CLRMD/docs/MachineCode.md
        // All the common code was copied from the MemStats project "dotnetsamples-master\Microsoft.Diagnostics.Runtime\CLRMD\MemStats\Program.cs"
        static void Main(string[] args)
        {
            string dump, dac;

            if (!TryParseArgs(args, out dump, out dac))
            {
                Usage();
                Environment.Exit(1);
            }

            try
            {
                // Create a ClrRuntime instance from the dump and dac location.  The ClrRuntime
                // object represents a version of CLR loaded in the process.  It contains data
                // such as the managed threads in the process, the AppDomains in the process,
                // the managed heap, and so on.
                //ClrRuntime runtime = CreateRuntime(dump, dac);

                // 1. Get the ClrType object for the type the method is on
                // 2. Get the ClrMethod object for the method
                // 3. Get the offset of the native code
                // 4. Compute the end address by mapping the IL instruction to addresses
                // 5. Disassemble the native code contained in that range (not provided by CLRMD)

                using (DataTarget dt = DataTarget.LoadCrashDump(dump))
                {
                    // Boilerplate.
                    //ClrRuntime runtime = dt.CreateRuntime(dt.ClrVersions.Single().TryDownloadDac());
                    var version = dt.ClrVersions.Single();
                    //{v4.0.30319.18444}
                    //version.Version = new VersionInfo { Major = 4, Minor = 0, Patch = 30319, Revision = 18444 };
                    Console.WriteLine("CLR Version: {0} ({1}), Dac: {2}", version.Version, version.Flavor, version.DacInfo);
                    var dacFileName = version.TryDownloadDac();
                    Console.WriteLine("DacFile: " + Path.GetFileName(dacFileName));
                    Console.WriteLine("DacPath: " + Path.GetDirectoryName(dacFileName));
                    ClrRuntime runtime = dt.CreateRuntime(dacFileName);
                    ClrHeap    heap    = runtime.GetHeap();

                    PrintDiagnosticInfo(dt, runtime, heap);
                    Console.WriteLine();

                    // Note heap.GetTypeByName doesn't always get you the type, even if it exists, due to
                    // limitations in the dac private apis that ClrMD is written on.  If you have the ClrType
                    // already via other means (heap walking, stack walking, etc), then that's better than
                    // using GetTypeByName:
                    var     classNameWithNamespace = "JITterOptimisations.Program";
                    ClrType @class = heap.GetTypeByName(classNameWithNamespace);

                    // Get the method you are looking for.
                    var       signature = "JITterOptimisations.Program.Log(System.ConsoleColor, System.String)";
                    ClrMethod @method   = @class.Methods.Single(m => m.GetFullSignature() == signature);

                    // This is the first instruction of the JIT'ed (or NGEN'ed) machine code.
                    ulong startAddress = @method.NativeCode;

                    // Unfortunately there's not a great way to get the size of the code, or the end address.
                    // This is partly due to the fact that we don't *have* to put all the JIT'ed code into one
                    // contiguous chunk, though I think an implementation detail is that we actually do.
                    // You are supposed to do code flow analysis like "uf" in windbg to find the size, but
                    // in practice you can use the IL to native mapping:
                    ulong endAddress = @method.ILOffsetMap.Select(entry => entry.EndAddress).Max();

                    var lines =
                        File.ReadAllLines(
                            @"C:\Users\warma11\Documents\Visual Studio 2013\Projects\JITterOptimisations\JITterOptimisations\Program.cs");

                    PrintILToNativeOffsetAlternative(method, lines);

                    // This doesn't seem to work as expected, using alternative method (above)
                    //PrintILToNativeOffsets(method, startAddress, lines);

                    // So the assembly code for the function is is in the range [startAddress, endAddress] inclusive.
                    var count = (int)endAddress + runtime.PointerSize - (int)startAddress;
                    Console.WriteLine("\nCode startAddress 0x{0:X} -> endAddress 0x{1:X} (inclusive), will read {2} bytes", startAddress, endAddress, count);

                    var bytes = new byte[count];
                    int bytesRead;
                    runtime.ReadMemory(startAddress, bytes, count, out bytesRead);
                    if (count != bytesRead)
                    {
                        Console.WriteLine("Expected to read {0} bytes, but only read {1}\n", count, bytesRead);
                    }
                    else
                    {
                        Console.WriteLine("Read read {0} bytes, as expected\n", bytesRead);
                    }
                    var fileName = string.Format("result-{0}bit.bin", runtime.PointerSize == 8 ? 64 : 32);
                    if (File.Exists(fileName))
                    {
                        File.Delete(fileName);
                    }
                    File.WriteAllBytes(fileName, bytes);

                    var filename =
                        @"C:\Users\warma11\Downloads\__GitHub__\dotnetsamples\Microsoft.Diagnostics.Runtime\CLRMD\MachineCode\nasm-2.11.05-win32\ndisasm.exe";
                    var currentFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                    var arguments     = "-b32 " + Path.Combine(currentFolder, fileName); // +" -o " + startAddress;
                    var disassembly   = Disassembler.GetDisassembly(filename, arguments, timeoutMsecs: 250);

                    var assemblyData = Disassembler.ProcessDisassembly(disassembly);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Unhandled exception:");
                Console.WriteLine(ex);
            }
        }