Exemplo n.º 1
0
        private static void WriteStackObjects(ClrRuntime runtime, ClrThread thread, TextWriter output)
        {
            var heap = runtime.Heap;

            var start = thread.StackBase;
            var stop  = thread.StackLimit;

            if (start > stop)
            {
                Util.Swap(ref start, ref stop);
            }

            output.WriteLine("Stack objects:");

            for (var ptr = start; ptr <= stop; ptr += (ulong)runtime.PointerSize)
            {
                if (!runtime.ReadPointer(ptr, out var obj))
                {
                    break;
                }

                var type = heap.GetObjectType(obj);
                if (type == null)
                {
                    continue;
                }
                if (type.IsFree)
                {
                    continue;
                }

                output.WriteLine("{0,16:X} {1,16:X} {2}", ptr, obj, type.Name);
            }
        }
Exemplo n.º 2
0
        public ulong ReadPointer(ulong Address)
        {
            StartRuntime();
            ulong ptr;

            m_runtime.ReadPointer(Address, out ptr);
            return(ptr);
        }
Exemplo n.º 3
0
        private static void DumpStack(ClrRuntime runtime, ClrThread thread)
        {
            // We'll need heap data to find objects on the stack.
            var heap = runtime.Heap;

            // Walk each pointer aligned address on the stack.  Note that StackBase/StackLimit
            // is exactly what they are in the TEB.  This means StackBase > StackLimit on AMD64.
            var start = thread.StackBase;
            var stop  = thread.StackLimit;

            // We'll walk these in pointer order.
            if (start > stop)
            {
                var tmp = start;
                start = stop;
                stop  = tmp;
            }

            Log.Information("Stack objects:");

            // Walk each pointer aligned address.  Ptr is a stack address.
            for (var ptr = start; ptr <= stop; ptr += (ulong)runtime.PointerSize)
            {
                // Read the value of this pointer.  If we fail to read the memory, break.  The
                // stack region should be in the crash dump.
                if (!runtime.ReadPointer(ptr, out var obj))
                {
                    break;
                }

                // We check to see if this address is a valid object by simply calling
                // GetObjectType.  If that returns null, it's not an object.
                var type = heap.GetObjectType(obj);
                if (type == null)
                {
                    continue;
                }

                // Don't print out free objects as there tends to be a lot of them on
                // the stack.
                if (type.IsFree)
                {
                    continue;
                }

                Log.Information("{pointer,16:X} {object,16:X} {typeName}", ptr, obj, type.Name);

                try
                {
                    WriteFields(obj, type);
                }
                catch (Exception e)
                {
                    Log.Error("Failed to write values");
                }
            }
        }
Exemplo n.º 4
0
        private static List <string> GetStackObjects(ClrRuntime runtime, ClrThread thread)
        {
            var stackObjects = new List <string>();

            var heap = runtime.Heap;

            // Walk each pointer aligned address on the stack.  Note that StackBase/StackLimit
            // is exactly what they are in the TEB.  This means StackBase > StackLimit on AMD64.
            var start = thread.StackBase;
            var stop  = thread.StackLimit;

            // We'll walk these in pointer order.
            if (start > stop)
            {
                var tmp = start;
                start = stop;
                stop  = tmp;
            }

            // Walk each pointer aligned address.  Ptr is a stack address.
            for (var ptr = start; ptr <= stop; ptr += (ulong)runtime.PointerSize)
            {
                // Read the value of this pointer.  If we fail to read the memory, break.  The
                // stack region should be in the crash dump.
                if (runtime.ReadPointer(ptr, out var obj) == false)
                {
                    break;
                }

                // 003DF2A4
                // We check to see if this address is a valid object by simply calling
                // GetObjectType.  If that returns null, it's not an object.
                var type = heap.GetObjectType(obj);
                if (type == null)
                {
                    continue;
                }

                // Don't print out free objects as there tends to be a lot of them on
                // the stack.
                if (type.IsFree)
                {
                    continue;
                }

                stackObjects.Add(type.Name);
            }

            return(stackObjects);
        }
Exemplo n.º 5
0
        public override bool TryGetSymbolCore(ulong address, out SymbolResolverResult result)
        {
            const ulong MIN_ADDR = 0x10000;

            if (address < MIN_ADDR)
            {
                result = default;
                return(false);
            }

            string name;

            name = clrRuntime.GetJitHelperFunctionName(address);
            if (!(name is null))
            {
                result = new SymbolResolverResult(SymbolKind.Function, name, address);
                return(true);
            }

            name = clrRuntime.GetMethodTableName(address);
            if (!(name is null))
            {
                result = new SymbolResolverResult(SymbolKind.Data, "methodtable(" + name + ")", address);
                return(true);
            }

            var method = clrRuntime.GetMethodByAddress(address);

            if (method is null && (address & ((uint)clrRuntime.PointerSize - 1)) == 0)
            {
                if (clrRuntime.ReadPointer(address, out ulong newAddress) && newAddress >= MIN_ADDR)
                {
                    method = clrRuntime.GetMethodByAddress(newAddress);
                }
            }
            if (!(method is null))
            {
                result = new SymbolResolverResult(SymbolKind.Function, method.ToString(), address);
                return(true);
            }

            result = default;
            return(false);
        }
Exemplo n.º 6
0
        public override bool TryGetSymbolCore(ulong address, out SymbolResolverResult result)
        {
            string name;

            name = clrRuntime.GetJitHelperFunctionName(address);
            if (name != null)
            {
                result = new SymbolResolverResult(SymbolKind.Function, name, address);
                return(true);
            }

            name = clrRuntime.GetMethodTableName(address);
            if (name != null)
            {
                result = new SymbolResolverResult(SymbolKind.Data, "methodtable(" + name + ")", address);
                return(true);
            }

            var method = clrRuntime.GetMethodByAddress(address);

            if (method == null && address >= 0x10000)
            {
                if (clrRuntime.ReadPointer(address, out ulong newAddress))
                {
                    method = clrRuntime.GetMethodByAddress(newAddress);
                }
            }
            if (method != null)
            {
                result = new SymbolResolverResult(SymbolKind.Function, method.ToString(), method.NativeCode);
                return(true);
            }

            result = default;
            return(false);
        }
Exemplo n.º 7
0
        static void Main(string[] args)
        {
            string dump = string.Empty, dac = string.Empty;
            bool   dso = false;
            int    pid = Convert.ToInt32(args[0]);
            //if (!TryParseArgs(args, out dump, out dac, out dso))
            //{
            //    Usage();
            //    return;
            //}

            ClrRuntime runtime = CreateRuntime(pid, dump, dac);

            // Walk each thread in the process.
            foreach (ClrThread thread in runtime.Threads)
            {
                // The ClrRuntime.Threads will also report threads which have recently died, but their
                // underlying datastructures have not yet been cleaned up.  This can potentially be
                // useful in debugging (!threads displays this information with XXX displayed for their
                // OS thread id).  You cannot walk the stack of these threads though, so we skip them
                // here.
                if (!thread.IsAlive)
                {
                    continue;
                }

                Console.WriteLine("Thread {0:X}:", thread.OSThreadId);
                Console.WriteLine("Stack: {0:X} - {1:X}", thread.StackBase, thread.StackLimit);

                // Each thread tracks a "last thrown exception".  This is the exception object which
                // !threads prints.  If that exception object is present, we will display some basic
                // exception data here.  Note that you can get the stack trace of the exception with
                // ClrHeapException.StackTrace (we don't do that here).
                ClrException exception = thread.CurrentException;
                if (exception != null)
                {
                    Console.WriteLine("Exception: {0:X} ({1}), HRESULT={2:X}", exception.Address, exception.Type.Name, exception.HResult);
                }

                // Walk the stack of the thread and print output similar to !ClrStack.
                Console.WriteLine();
                Console.WriteLine("Managed Callstack:");
                foreach (ClrStackFrame frame in thread.StackTrace)
                {
                    // Note that CLRStackFrame currently only has three pieces of data: stack pointer,
                    // instruction pointer, and frame name (which comes from ToString).  Future
                    // versions of this API will allow you to get the type/function/module of the
                    // method (instead of just the name).  This is not yet implemented.
                    Console.WriteLine("{0,16:X} {1,16:X} {2}", frame.StackPointer, frame.InstructionPointer, frame.DisplayString);
                }

                // Print a !DumpStackObjects equivalent.
                if (dso)
                {
                    // We'll need heap data to find objects on the stack.
                    ClrHeap heap = runtime.Heap;

                    // Walk each pointer aligned address on the stack.  Note that StackBase/StackLimit
                    // is exactly what they are in the TEB.  This means StackBase > StackLimit on AMD64.
                    ulong start = thread.StackBase;
                    ulong stop  = thread.StackLimit;

                    // We'll walk these in pointer order.
                    if (start > stop)
                    {
                        ulong tmp = start;
                        start = stop;
                        stop  = tmp;
                    }

                    Console.WriteLine();
                    Console.WriteLine("Stack objects:");

                    // Walk each pointer aligned address.  Ptr is a stack address.
                    for (ulong ptr = start; ptr <= stop; ptr += (ulong)runtime.PointerSize)
                    {
                        // Read the value of this pointer.  If we fail to read the memory, break.  The
                        // stack region should be in the crash dump.
                        ulong obj;
                        if (!runtime.ReadPointer(ptr, out obj))
                        {
                            break;
                        }

                        // 003DF2A4
                        // We check to see if this address is a valid object by simply calling
                        // GetObjectType.  If that returns null, it's not an object.
                        ClrType type = heap.GetObjectType(obj);
                        if (type == null)
                        {
                            continue;
                        }

                        // Don't print out free objects as there tends to be a lot of them on
                        // the stack.
                        if (!type.IsFree)
                        {
                            Console.WriteLine("{0,16:X} {1,16:X} {2}", ptr, obj, type.Name);
                        }
                    }
                }

                Console.WriteLine();
                Console.WriteLine("----------------------------------");
                Console.WriteLine();
            }
        }
Exemplo n.º 8
0
        public int ReadPtr(ulong addr, out ulong pValue)
        {
            bool success = m_runtime.ReadPointer(addr, out pValue);

            return(success ? 1 : 0);
        }
Exemplo n.º 9
0
 /// <summary>
 ///     Reads a pointer value out of the target process.  This function reads only the target's pointer size,
 ///     so if this is used on an x86 target, only 4 bytes is read and written to val.
 /// </summary>
 /// <param name="address">The address to read from.</param>
 /// <param name="value">The value at that address.</param>
 /// <returns>True if the read was successful, false otherwise.</returns>
 /// <inheritdoc />
 public bool ReadPointer(ulong address, out ulong value) => Runtime.ReadPointer(address, out value);
Exemplo n.º 10
0
        private bool GetReferencedAddressToMethodName(out ulong refAddress, out uint codeSize, out string name, Instruction instruction, ClrRuntime runtime)
        {
            name       = null;
            refAddress = 0;
            codeSize   = 0;

            bool isAddressOk = false;

            for (int i = 0; i < instruction.OpCount; i++)
            {
                switch (instruction.GetOpKind(i))
                {
                case OpKind.NearBranch16:
                case OpKind.NearBranch32:
                case OpKind.NearBranch64:
                    refAddress  = instruction.NearBranchTarget;
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;

                case OpKind.Immediate64:
                    refAddress  = instruction.GetImmediate(i);
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;

                case OpKind.Memory64:
                    refAddress  = instruction.MemoryAddress64;
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;

                case OpKind.Memory when instruction.IsIPRelativeMemoryOperand:
                    refAddress  = instruction.IPRelativeMemoryAddress;
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;

                case OpKind.Memory:
                    refAddress  = instruction.MemoryDisplacement;
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;
                }
            }

            if (refAddress == 0)
            {
                return(false);
            }

            var jitHelperFunctionName = runtime.GetJitHelperFunctionName(refAddress);

            if (string.IsNullOrWhiteSpace(jitHelperFunctionName) == false)
            {
                name = jitHelperFunctionName;
                return(true);
            }

            var methodTableName = runtime.GetMethodTableName(refAddress);

            if (string.IsNullOrWhiteSpace(methodTableName) == false)
            {
                name = methodTableName;
                return(true);
            }

            var methodDescriptor = runtime.GetMethodByHandle(refAddress);

            if (methodDescriptor != null)
            {
                name       = methodDescriptor.Name;
                refAddress = methodDescriptor.HotColdInfo.HotStart;
                codeSize   = methodDescriptor.HotColdInfo.HotSize;
                return(true);
            }

            var methodCall = runtime.GetMethodByAddress(refAddress);

            if (methodCall != null && string.IsNullOrWhiteSpace(methodCall.Name) == false)
            {
                name       = methodCall.Name;
                refAddress = methodCall.HotColdInfo.HotStart;
                codeSize   = methodCall.HotColdInfo.HotSize;
                return(true);
            }

            if (methodCall == null)
            {
                if (runtime.ReadPointer(refAddress, out ulong newAddress) && newAddress > ushort.MaxValue)
                {
                    methodCall = runtime.GetMethodByAddress(newAddress);
                }

                if (methodCall is null)
                {
                    return(false);
                }

                name       = methodCall.Name;
                refAddress = methodCall.HotColdInfo.HotStart;
                codeSize   = methodCall.HotColdInfo.HotSize;

                return(true);
            }

            return(false);
        }