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);
                }
            }
Exemple #2
0
            private void ProcessFrame(IXCLRDataStackWalk stackWalk)
            {
                object tmp;

                if (HR.Failed(stackWalk.GetFrame(out tmp)))
                    return;

                IXCLRDataFrame frame = (IXCLRDataFrame)tmp;

                StringBuilder methodName = new StringBuilder(MaxNameSize);
                uint methodNameLen;
                if (HR.Failed(frame.GetCodeName(0 /*default flags*/, (uint)methodName.Capacity, out methodNameLen, methodName)))
                    return;

                uint numArgs, numLocals;
                if (HR.Failed(frame.GetNumArguments(out numArgs)))
                    numArgs = 0;
                if (HR.Failed(frame.GetNumLocalVariables(out numLocals)))
                    numLocals = 0;

                FrameArgumentsAndLocals frameArgsLocals = new FrameArgumentsAndLocals()
                {
                    MethodName = methodName.ToString()
                };
                for (uint argIdx = 0; argIdx < numArgs; ++argIdx)
                {
                    StringBuilder argName = new StringBuilder(MaxNameSize);
                    uint argNameLen;

                    if (FailedUnlessOnCLR2DAC(frame.GetArgumentByIndex(argIdx, out tmp, (uint)argName.Capacity, out argNameLen, argName)) ||
                        tmp == null)
                        continue;

                    var arg = new ArgumentOrLocal() { Name = argName.ToString() };
                    FillValue(arg, (IXCLRDataValue)tmp);
                    frameArgsLocals.Arguments.Add(arg);
                }

                for (uint lclIdx = 0; lclIdx < numLocals; ++lclIdx)
                {
                    // The mscordacwks!ClrDataFrame::GetLocalVariableByIndex implementation never returns
                    // names for local variables. Need to go through metadata to get them.
                    StringBuilder dummy = new StringBuilder(2);
                    uint lclNameLen;
                    if (FailedUnlessOnCLR2DAC(frame.GetLocalVariableByIndex(lclIdx, out tmp, (uint)dummy.Capacity, out lclNameLen, dummy)) ||
                        tmp == null)
                        continue;

                    string lclName = dummy.ToString();
                    var matchingFrame = _stackTrace.SingleOrDefault(f => f.DisplayString == frameArgsLocals.MethodName);
                    if (matchingFrame != null)
                    {
                        lclName = GetLocalVariableName(matchingFrame.InstructionPointer, lclIdx);
                    }

                    var lcl = new ArgumentOrLocal() { Name = lclName };
                    FillValue(lcl, (IXCLRDataValue)tmp);
                    frameArgsLocals.LocalVariables.Add(lcl);
                }

                _results.Add(frameArgsLocals);
            }
            private void ProcessFrame(IXCLRDataStackWalk stackWalk)
            {
                object tmp;

                if (HR.Failed(stackWalk.GetFrame(out tmp)))
                {
                    return;
                }

                IXCLRDataFrame frame = (IXCLRDataFrame)tmp;

                StringBuilder methodName = new StringBuilder(MaxNameSize);
                uint          methodNameLen;

                if (HR.Failed(frame.GetCodeName(0 /*default flags*/, (uint)methodName.Capacity, out methodNameLen, methodName)))
                {
                    return;
                }

                uint numArgs, numLocals;

                if (HR.Failed(frame.GetNumArguments(out numArgs)))
                {
                    numArgs = 0;
                }
                if (HR.Failed(frame.GetNumLocalVariables(out numLocals)))
                {
                    numLocals = 0;
                }

                FrameArgumentsAndLocals frameArgsLocals = new FrameArgumentsAndLocals()
                {
                    MethodName = methodName.ToString()
                };

                for (uint argIdx = 0; argIdx < numArgs; ++argIdx)
                {
                    StringBuilder argName = new StringBuilder(MaxNameSize);
                    uint          argNameLen;

                    if (FailedUnlessOnCLR2DAC(frame.GetArgumentByIndex(argIdx, out tmp, (uint)argName.Capacity, out argNameLen, argName)) ||
                        tmp == null)
                    {
                        continue;
                    }

                    var arg = new ArgumentOrLocal()
                    {
                        Name = argName.ToString()
                    };
                    FillValue(arg, (IXCLRDataValue)tmp);
                    frameArgsLocals.Arguments.Add(arg);
                }

                for (uint lclIdx = 0; lclIdx < numLocals; ++lclIdx)
                {
                    // The mscordacwks!ClrDataFrame::GetLocalVariableByIndex implementation never returns
                    // names for local variables. Need to go through metadata to get them.
                    StringBuilder dummy = new StringBuilder(2);
                    uint          lclNameLen;
                    if (FailedUnlessOnCLR2DAC(frame.GetLocalVariableByIndex(lclIdx, out tmp, (uint)dummy.Capacity, out lclNameLen, dummy)) ||
                        tmp == null)
                    {
                        continue;
                    }

                    string lclName       = dummy.ToString();
                    var    matchingFrame = _stackTrace.SingleOrDefault(f => f.DisplayString == frameArgsLocals.MethodName);
                    if (matchingFrame != null)
                    {
                        lclName = GetLocalVariableName(matchingFrame.InstructionPointer, lclIdx);
                    }

                    var lcl = new ArgumentOrLocal()
                    {
                        Name = lclName
                    };
                    FillValue(lcl, (IXCLRDataValue)tmp);
                    frameArgsLocals.LocalVariables.Add(lcl);
                }

                _results.Add(frameArgsLocals);
            }
Exemple #4
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);
                }
            }
        }