Пример #1
0
            private void ProcessStackWalk(uint osThreadId)
            {
                IXCLRDataProcess ixclrDataProcess = _context.Runtime.DacInterface;

                object tmp;

                HR.Verify(ixclrDataProcess.GetTaskByOSThreadID(osThreadId, out tmp));

                IXCLRDataTask task = (IXCLRDataTask)tmp;

                HR.Verify(task.CreateStackWalk(0xf /*all flags*/, out tmp));

                IXCLRDataStackWalk stackWalk = (IXCLRDataStackWalk)tmp;

                while (HR.S_OK == stackWalk.Next())
                {
                    ProcessFrame(stackWalk);
                }
            }
Пример #2
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);
                }
            }
        }