Пример #1
0
        protected override DesktopStackFrame GetStackFrame(DesktopThread thread, byte[] context, ulong ip, ulong framePtr, ulong frameVtbl)
        {
            DesktopStackFrame frame;

            if (frameVtbl != 0)
            {
                ClrMethod innerMethod = null;
                string    frameName   = _sos.GetFrameName(frameVtbl);

                ulong md = _sos.GetMethodDescPtrFromFrame(framePtr);
                if (md != 0)
                {
                    V45MethodDescDataWrapper mdData = new V45MethodDescDataWrapper();
                    if (mdData.Init(_sos, md))
                    {
                        innerMethod = DesktopMethod.Create(this, mdData);
                    }
                }

                frame = new DesktopStackFrame(this, thread, context, framePtr, frameName, innerMethod);
            }
            else
            {
                frame = new DesktopStackFrame(this, thread, context, ip, framePtr, _sos.GetMethodDescPtrFromIP(ip));
            }

            return(frame);
        }
Пример #2
0
        protected override DesktopStackFrame GetStackFrame(DesktopThread thread, byte[] context, ulong ip, ulong sp, ulong frameVtbl)
        {
            DesktopStackFrame frame;

            ClearBuffer();

            if (frameVtbl != 0)
            {
                ClrMethod method    = null;
                string    frameName = "Unknown Frame";
                if (Request(DacRequests.FRAME_NAME, frameVtbl, _buffer))
                {
                    frameName = BytesToString(_buffer);
                }

                IMethodDescData mdData = GetMethodDescData(DacRequests.METHODDESC_FRAME_DATA, sp);
                if (mdData != null)
                {
                    method = DesktopMethod.Create(this, mdData);
                }

                frame = new DesktopStackFrame(this, thread, context, sp, frameName, method);
            }
            else
            {
                ulong md = GetMethodDescFromIp(ip);
                frame = new DesktopStackFrame(this, thread, context, ip, sp, md);
            }

            return(frame);
        }
Пример #3
0
 public DesktopStackFrame(DesktopRuntimeBase runtime, DesktopThread thread, ulong sp, string method, ClrMethod innerMethod)
 {
     _runtime   = runtime;
     _thread    = thread;
     _sp        = sp;
     _frameName = method ?? "Unknown";
     _type      = ClrStackFrameType.Runtime;
     _method    = innerMethod;
 }
Пример #4
0
        public DesktopStackFrame(DesktopRuntimeBase runtime, DesktopThread thread, ulong sp, ulong md)
        {
            _runtime   = runtime;
            _thread    = thread;
            _sp        = sp;
            _frameName = _runtime.GetNameForMD(md) ?? "Unknown";
            _type      = ClrStackFrameType.Runtime;

            InitMethod(md);
        }
Пример #5
0
 public override IEnumerable <int> EnumerateGCThreads()
 {
     foreach (uint thread in _dataReader.EnumerateAllThreads())
     {
         ulong teb        = _dataReader.GetThreadTeb(thread);
         int   threadType = DesktopThread.GetTlsSlotForThread(this, teb);
         if ((threadType & (int)DesktopThread.TlsThreadType.ThreadType_GC) == (int)DesktopThread.TlsThreadType.ThreadType_GC)
         {
             yield return((int)thread);
         }
     }
 }
Пример #6
0
        public DesktopStackFrame(DesktopRuntimeBase runtime, DesktopThread thread, byte[] context, ulong ip, ulong sp, ulong md)
        {
            _runtime     = runtime;
            _thread      = thread;
            _context     = context;
            _ip          = ip;
            StackPointer = sp;
            _frameName   = _runtime.GetNameForMD(md) ?? "Unknown";
            _type        = ClrStackFrameType.ManagedMethod;

            InitMethod(md);
        }
Пример #7
0
        internal IEnumerable <ClrStackFrame> EnumerateStackFrames(DesktopThread thread)
        {
            using (ClrStackWalk stackwalk = _dacInterface.CreateStackWalk(thread.OSThreadId, 0xf))
            {
                if (stackwalk == null)
                {
                    yield break;
                }

                byte[] ulongBuffer = new byte[8];
                byte[] context     = ContextHelper.Context;
                do
                {
                    if (!stackwalk.GetContext(ContextHelper.ContextFlags, ContextHelper.Length, out uint size, context))
                    {
                        break;
                    }

                    ulong ip, sp;

                    if (PointerSize == 4)
                    {
                        ip = BitConverter.ToUInt32(context, ContextHelper.InstructionPointerOffset);
                        sp = BitConverter.ToUInt32(context, ContextHelper.StackPointerOffset);
                    }
                    else
                    {
                        ip = BitConverter.ToUInt64(context, ContextHelper.InstructionPointerOffset);
                        sp = BitConverter.ToUInt64(context, ContextHelper.StackPointerOffset);
                    }

                    ulong frameVtbl = stackwalk.GetFrameVtable();
                    if (frameVtbl != 0)
                    {
                        sp = frameVtbl;
                        ReadPointer(sp, out frameVtbl);
                    }

                    byte[] contextCopy = new byte[context.Length];
                    Buffer.BlockCopy(context, 0, contextCopy, 0, context.Length);

                    DesktopStackFrame frame = GetStackFrame(thread, contextCopy, ip, sp, frameVtbl);
                    yield return(frame);
                } while (stackwalk.Next());
            }
        }
Пример #8
0
        internal override IList <ClrStackFrame> GetExceptionStackTrace(ulong obj, ClrType type)
        {
            // TODO: Review this and if it works on v4.5, merge the two implementations back into RuntimeBase.
            List <ClrStackFrame> result = new List <ClrStackFrame>();

            if (type == null)
            {
                return(result);
            }

            if (!GetStackTraceFromField(type, obj, out ulong _stackTrace))
            {
                if (!ReadPointer(obj + GetStackTraceOffset(), out _stackTrace))
                {
                    return(result);
                }
            }

            if (_stackTrace == 0)
            {
                return(result);
            }

            ClrHeap heap           = Heap;
            ClrType stackTraceType = heap.GetObjectType(_stackTrace);

            if (stackTraceType == null || !stackTraceType.IsArray)
            {
                return(result);
            }

            int len = stackTraceType.GetArrayLength(_stackTrace);

            if (len == 0)
            {
                return(result);
            }

            int   elementSize = IntPtr.Size * 4;
            ulong dataPtr     = _stackTrace + (ulong)(IntPtr.Size * 2);

            if (!ReadPointer(dataPtr, out ulong count))
            {
                return(result);
            }

            // Skip size and header
            dataPtr += (ulong)(IntPtr.Size * 2);

            DesktopThread thread = null;

            for (int i = 0; i < (int)count; ++i)
            {
                if (!ReadPointer(dataPtr, out ulong ip))
                {
                    break;
                }
                if (!ReadPointer(dataPtr + (ulong)IntPtr.Size, out ulong sp))
                {
                    break;
                }
                if (!ReadPointer(dataPtr + (ulong)(2 * IntPtr.Size), out ulong md))
                {
                    break;
                }

                if (i == 0 && sp != 0)
                {
                    thread = (DesktopThread)GetThreadByStackAddress(sp);
                }

                // it seems that the first frame often has 0 for IP and SP.  Try the 2nd frame as well
                if (i == 1 && thread == null && sp != 0)
                {
                    thread = (DesktopThread)GetThreadByStackAddress(sp);
                }

                result.Add(new DesktopStackFrame(this, thread, null, ip, sp, md));

                dataPtr += (ulong)elementSize;
            }

            return(result);
        }
Пример #9
0
 protected abstract DesktopStackFrame GetStackFrame(DesktopThread thread, int res, ulong ip, ulong sp, ulong frameVtbl);
Пример #10
0
        internal override IList <ClrStackFrame> GetExceptionStackTrace(ulong obj, ClrType type)
        {
            List <ClrStackFrame> result = new List <ClrStackFrame>();

            if (!GetStackTraceFromField(type, obj, out ulong _stackTrace))
            {
                if (!ReadPointer(obj + GetStackTraceOffset(), out _stackTrace))
                {
                    return(result);
                }
            }

            if (_stackTrace == 0)
            {
                return(result);
            }

            DesktopGCHeap heap           = (DesktopGCHeap)Heap;
            ClrType       stackTraceType = heap.GetObjectType(_stackTrace);

            if (stackTraceType == null)
            {
                stackTraceType = heap.ArrayType;
            }

            if (!stackTraceType.IsArray)
            {
                return(result);
            }

            int len = stackTraceType.GetArrayLength(_stackTrace);

            if (len == 0)
            {
                return(result);
            }

            int   elementSize = CLRVersion == DesktopVersion.v2 ? IntPtr.Size * 4 : IntPtr.Size * 3;
            ulong dataPtr     = _stackTrace + (ulong)(IntPtr.Size * 2);

            if (!ReadPointer(dataPtr, out ulong count))
            {
                return(result);
            }

            // Skip size and header
            dataPtr += (ulong)(IntPtr.Size * 2);

            DesktopThread thread = null;

            for (int i = 0; i < (int)count; ++i)
            {
                if (!ReadPointer(dataPtr, out ulong ip))
                {
                    break;
                }
                if (!ReadPointer(dataPtr + (ulong)IntPtr.Size, out ulong sp))
                {
                    break;
                }
                if (!ReadPointer(dataPtr + (ulong)(2 * IntPtr.Size), out ulong md))
                {
                    break;
                }

                if (i == 0)
                {
                    thread = (DesktopThread)GetThreadByStackAddress(sp);
                }

                result.Add(new DesktopStackFrame(this, thread, null, ip, sp, md));

                dataPtr += (ulong)elementSize;
            }

            return(result);
        }
Пример #11
0
 protected abstract DesktopStackFrame GetStackFrame(DesktopThread thread, int res, ulong ip, ulong sp, ulong frameVtbl);
Пример #12
0
        internal IEnumerable<ClrStackFrame> EnumerateStackFrames(DesktopThread thread)
        {
            IXCLRDataProcess proc = GetClrDataProcess();
            object tmp;

            int res = proc.GetTaskByOSThreadID(thread.OSThreadId, out tmp);
            if (res < 0)
                yield break;

            IXCLRDataTask task = null;
            IXCLRDataStackWalk stackwalk = null;

            try
            {
                task = (IXCLRDataTask)tmp;
                res = task.CreateStackWalk(0xf, out tmp);
                if (res < 0)
                    yield break;

                stackwalk = (IXCLRDataStackWalk)tmp;
                byte[] ulongBuffer = new byte[8];
                byte[] context = ContextHelper.Context;
                do
                {
                    uint size;
                    res = stackwalk.GetContext(ContextHelper.ContextFlags, ContextHelper.Length, out size, context);
                    if (res < 0 || res == 1)
                        break;

                    ulong ip = BitConverter.ToUInt32(context, ContextHelper.InstructionPointerOffset);
                    ulong sp = BitConverter.ToUInt32(context, ContextHelper.StackPointerOffset);

                    res = stackwalk.Request(0xf0000000, 0, null, (uint)ulongBuffer.Length, ulongBuffer);

                    ulong frameVtbl = 0;
                    if (res >= 0)
                    {
                        frameVtbl = BitConverter.ToUInt64(ulongBuffer, 0);
                        if (frameVtbl != 0)
                        {
                            sp = frameVtbl;
                            ReadPointer(sp, out frameVtbl);
                        }
                    }

                    DesktopStackFrame frame = GetStackFrame(thread, res, ip, sp, frameVtbl);
                    yield return frame;
                } while (stackwalk.Next() == 0);
            }
            finally
            {
                if (task != null)
                    Marshal.FinalReleaseComObject(task);

                if (stackwalk != null)
                    Marshal.FinalReleaseComObject(stackwalk);
            }
        }
Пример #13
0
        public DesktopStackFrame(DesktopRuntimeBase runtime, DesktopThread thread, ulong ip, ulong sp, ulong md)
        {
            _runtime = runtime;
            _thread = thread;
            _ip = ip;
            _sp = sp;
            _frameName = _runtime.GetNameForMD(md) ?? "Unknown";
            _type = ClrStackFrameType.ManagedMethod;

            InitMethod(md);
        }
Пример #14
0
 public DesktopStackFrame(DesktopRuntimeBase runtime, DesktopThread thread, ulong sp, string method, ClrMethod innerMethod)
 {
     _runtime = runtime;
     _thread = thread;
     _sp = sp;
     _frameName = method ?? "Unknown";
     _type = ClrStackFrameType.Runtime;
     _method = innerMethod;
 }
Пример #15
0
 protected abstract DesktopStackFrame GetStackFrame(DesktopThread thread, byte[] context, ulong ip, ulong sp, ulong frameVtbl);
Пример #16
0
        internal IEnumerable <ClrStackFrame> EnumerateStackFrames(DesktopThread thread)
        {
            IXCLRDataProcess proc = GetClrDataProcess();
            object           tmp;

            int res = proc.GetTaskByOSThreadID(thread.OSThreadId, out tmp);

            if (res < 0)
            {
                yield break;
            }

            IXCLRDataTask      task      = null;
            IXCLRDataStackWalk stackwalk = null;

            try
            {
                task = (IXCLRDataTask)tmp;
                res  = task.CreateStackWalk(0xf, out tmp);
                if (res < 0)
                {
                    yield break;
                }

                stackwalk = (IXCLRDataStackWalk)tmp;
                byte[] ulongBuffer = new byte[8];
                byte[] context     = ContextHelper.Context;
                do
                {
                    uint size;
                    res = stackwalk.GetContext(ContextHelper.ContextFlags, ContextHelper.Length, out size, context);
                    if (res < 0 || res == 1)
                    {
                        break;
                    }

                    ulong ip = BitConverter.ToUInt32(context, ContextHelper.InstructionPointerOffset);
                    ulong sp = BitConverter.ToUInt32(context, ContextHelper.StackPointerOffset);

                    res = stackwalk.Request(0xf0000000, 0, null, (uint)ulongBuffer.Length, ulongBuffer);

                    ulong frameVtbl = 0;
                    if (res >= 0)
                    {
                        frameVtbl = BitConverter.ToUInt64(ulongBuffer, 0);
                        if (frameVtbl != 0)
                        {
                            sp = frameVtbl;
                            ReadPointer(sp, out frameVtbl);
                        }
                    }

                    DesktopStackFrame frame = GetStackFrame(thread, res, ip, sp, frameVtbl);
                    yield return(frame);
                } while (stackwalk.Next() == 0);
            }
            finally
            {
                if (task != null)
                {
                    Marshal.FinalReleaseComObject(task);
                }

                if (stackwalk != null)
                {
                    Marshal.FinalReleaseComObject(stackwalk);
                }
            }
        }
Пример #17
0
        protected override DesktopStackFrame GetStackFrame(DesktopThread thread, int res, ulong ip, ulong framePtr, ulong frameVtbl)
        {
            DesktopStackFrame frame;
            StringBuilder sb = new StringBuilder();
            sb.Capacity = 256;
            uint needed;
            if (res >= 0 && frameVtbl != 0)
            {
                ClrMethod innerMethod = null;
                string frameName = "Unknown Frame";
                if (_sos.GetFrameName(frameVtbl, (uint)sb.Capacity, sb, out needed) >= 0)
                    frameName = sb.ToString();

                ulong md = 0;
                if (_sos.GetMethodDescPtrFromFrame(framePtr, out md) == 0)
                {
                    V45MethodDescDataWrapper mdData = new V45MethodDescDataWrapper();
                    if (mdData.Init(_sos, md))
                        innerMethod = DesktopMethod.Create(this, mdData);
                }

                frame = new DesktopStackFrame(this, thread, framePtr, frameName, innerMethod);
            }
            else
            {
                ulong md;
                if (_sos.GetMethodDescPtrFromIP(ip, out md) >= 0)
                {
                    frame = new DesktopStackFrame(this, thread, ip, framePtr, md);
                }
                else
                {
                    frame = new DesktopStackFrame(this, thread, ip, framePtr, 0);
                }
            }

            return frame;
        }
Пример #18
0
        protected override DesktopStackFrame GetStackFrame(DesktopThread thread, int res, ulong ip, ulong sp, ulong frameVtbl)
        {
            DesktopStackFrame frame;
            ClearBuffer();

            if (res >= 0 && frameVtbl != 0)
            {
                ClrMethod method = null;
                string frameName = "Unknown Frame";
                if (Request(DacRequests.FRAME_NAME, frameVtbl, _buffer))
                    frameName = BytesToString(_buffer);

                var mdData = GetMethodDescData(DacRequests.METHODDESC_FRAME_DATA, sp);
                if (mdData != null)
                    method = DesktopMethod.Create(this, mdData);

                frame = new DesktopStackFrame(this, thread, sp, frameName, method);
            }
            else
            {
                ulong md = GetMethodDescFromIp(ip);
                frame = new DesktopStackFrame(this, thread, ip, sp, md);
            }

            return frame;
        }