Пример #1
0
        public void VariableRootTest()
        {
            // Test to make sure that a specific static and local variable exist.

            using DataTarget dt      = TestTargets.Types.LoadFullDump();
            using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
            ClrHeap heap = runtime.Heap;

            IEnumerable <IClrRoot> fooRoots = from root in heap.EnumerateRoots()
                                              where root.Object.Type.Name == "Foo"
                                              select root;

            IClrRoot[] localVarRoots = fooRoots.Where(r => r.RootKind == ClrRootKind.Stack).ToArray();

            ClrThread     thread = runtime.GetMainThread();
            ClrStackFrame main   = thread.GetFrame("Main");
            ClrStackFrame inner  = thread.GetFrame("Inner");

            ulong low  = thread.StackBase;
            ulong high = thread.StackLimit;

            // Account for different platform stack direction.
            if (low > high)
            {
                ulong tmp = low;
                low  = high;
                high = tmp;
            }

            foreach (IClrRoot localVarRoot in localVarRoots)
            {
                Assert.True(low <= localVarRoot.Address && localVarRoot.Address <= high);
            }
        }
Пример #2
0
        private static string[] GetClrArgumentsNames(ClrStackFrame frame)
        {
            var           imd       = frame.Module.MetadataImport;
            var           sb        = new StringBuilder(64);
            List <string> arguments = new List <string>(frame.Arguments.Count);
            IntPtr        paramEnum = IntPtr.Zero;
            uint          fetched   = 0;
            int           paramDef;

            imd.EnumParams(ref paramEnum, (int)frame.Method.MetadataToken, out paramDef, 1, out fetched);
            while (fetched == 1)
            {
                int    pmd;
                uint   pulSequence, pchName, pdwAttr, pdwCPlusTypeFlag, pcchValue;
                IntPtr ppValue;

                imd.GetParamProps(paramDef, out pmd, out pulSequence, sb, (uint)sb.Capacity, out pchName, out pdwAttr, out pdwCPlusTypeFlag, out ppValue, out pcchValue);
                arguments.Add(sb.ToString());
                sb.Clear();
                imd.EnumParams(ref paramEnum, (int)frame.Method.MetadataToken, out paramDef, 1, out fetched);
            }

            imd.CloseEnum(paramEnum);
            if (arguments.Count == frame.Arguments.Count - 1)
            {
                arguments.Insert(0, "this");
            }

            return(arguments.ToArray());
        }
Пример #3
0
        private int FindIlOffset(ClrStackFrame frame)
        {
            if (frame.Kind != ClrStackFrameType.ManagedMethod ||
                frame.Method.ILOffsetMap == null)
            {
                return(-1);
            }

            ulong ip   = frame.InstructionPointer;
            int   last = -1;

            foreach (ILToNativeMap item in frame.Method.ILOffsetMap)
            {
                if (item.StartAddress > ip)
                {
                    return(last);
                }

                if (ip <= item.EndAddress)
                {
                    return(item.ILOffset);
                }

                last = item.ILOffset;
            }

            return(last);
        }
Пример #4
0
        public static SDCombinedStackFrame ToSDModel(this ClrStackFrame frame)
        {
            StackFrameType type =
                (frame.Kind == ClrStackFrameType.ManagedMethod) ? StackFrameType.Managed :
                (frame.Kind == ClrStackFrameType.Runtime) ? StackFrameType.Special :
                /* here be dragons */ StackFrameType.Special;


            string methodName;
            string moduleName = string.Empty;

            if (frame.Method == null)
            {
                methodName = frame.DisplayString;                 //for example GCFrame
            }
            else
            {
                methodName = frame.Method.GetFullSignature();
                if (frame.Method.Type != null)
                {
                    moduleName = Path.GetFileNameWithoutExtension(frame.Method.Type.Module.Name);
                    if (string.IsNullOrEmpty(moduleName))
                    {
                        moduleName = "UNKNOWN";
                    }
                }
            }
            return(new SDCombinedStackFrame(type, frame.InstructionPointer, frame.StackPointer, methodName, moduleName, frame.Method.NativeCode));
        }
Пример #5
0
        private static void SampleCpu(ClrRuntime runtime)
        {
            foreach (ClrThread thread in runtime.Threads)
            {
                StringBuilder sb = new StringBuilder();

                for (int i = thread.StackTrace.Count - 1; i >= 0; i--)
                {
                    ClrStackFrame stackFrame = thread.StackTrace[i];
                    if (!string.IsNullOrWhiteSpace(stackFrame.Method?.Type?.Name) ||
                        !string.IsNullOrWhiteSpace(stackFrame.Method?.Name))
                    {
                        sb.Append($"{stackFrame.Method?.Type?.Name}.{stackFrame.Method?.Name};");
                    }
                }

                // Trim the last ';'
                if (sb.Length > 0 && sb[sb.Length - 1] == ';')
                {
                    sb.Length = sb.Length - 1;
                }

                string stackString = sb.ToString();
                if (!string.IsNullOrWhiteSpace(stackString))
                {
                    ReportStackTrace(stackString);
                }

                runtime.Flush();
            }
        }
Пример #6
0
        public SDCombinedStackFrame(ClrStackFrame frame)
        {
            if (frame.Kind == ClrStackFrameType.ManagedMethod)
            {
                Type = StackFrameType.Managed;
            }
            if (frame.Kind == ClrStackFrameType.Runtime)
            {
                Type = StackFrameType.Special;
            }

            InstructionPointer = frame.InstructionPointer;
            StackPointer       = frame.StackPointer;


            if (frame.Method == null)
            {
                MethodName = frame.DisplayString;                 //for example GCFrame
                return;
            }

            MethodName = frame.Method.GetFullSignature();
            if (frame.Method.Type != null)
            {
                ModuleName = Path.GetFileNameWithoutExtension(frame.Method.Type.Module.Name);
            }

            // calculate IL offset with instruction pointer of frame and instruction pointer
            // in the target dump file of the start of the method's assembly
            OffsetInMethod = InstructionPointer - frame.Method.NativeCode;
        }
Пример #7
0
        public static FileAndLineNumber GetSourceLocation(this ClrStackFrame frame)
        {
            PdbReader reader = GetReaderForFrame(frame);

            if (reader is null)
            {
                return(default);
Пример #8
0
        public static List <StackFrameInfo> GetDetailedStackTrace(this ClrThread thread)
        {
            List <StackFrameInfo> stackframes = new List <StackFrameInfo>();

            List <ClrRoot> stackObjects = thread.EnumerateStackObjects().ToList();

            ulong lastAddress = 0;

            foreach (ClrStackFrame frame in thread.StackTrace)
            {
                ClrStackFrame     f = frame;
                List <ClrDynamic> objectsInFrame = stackObjects
                                                   .Where(o => o.Address > lastAddress && o.Address <= f.StackPointer)
                                                   .OrderBy(o => o.Address)
                                                   .Select(o => ClrMDSession.Current.Heap.GetDynamicObject(o.Object))
                                                   .ToList();

                stackframes.Add(new StackFrameInfo
                {
                    Function = f.DisplayString,
                    Objects  = objectsInFrame
                });

                lastAddress = f.StackPointer;
            }

            return(stackframes);
        }
Пример #9
0
        private void ComputeNames(ClrStackFrame frame)
        {
            // start by parsing (short)type name
            var typeName = frame.Method.Type.Name;

            if (string.IsNullOrEmpty(typeName))
            {
                // IL generated frames
                TypeName = string.Empty;
            }
            else
            {
                TypeName = typeName;
            }

            // generic methods are not well formatted by ClrMD
            // foo<...>()  =>   foo[[...]]()
#if ClrMD1
            var fullName = frame.Method?.GetFullSignature();
#else
            var fullName = frame.Method?.Signature;
#endif
            MethodName = frame.Method.Name;
            if (MethodName.EndsWith("]]"))
            {
                // fix ClrMD bug with method name
                MethodName = GetGenericMethodName(fullName);
            }

            Signature.AddRange(BuildSignature(fullName));
        }
Пример #10
0
 internal DbgStackFrameInfo(DbgEngDebugger debugger,
                            DbgUModeThreadInfo thread,
                            DEBUG_STACK_FRAME_EX nativeFrame,
                            ClrStackFrame managedFrame)
     : this(debugger, thread, nativeFrame, managedFrame, true)
 {
 }
Пример #11
0
        private FileAndLineNumber GetSourceLocation(ClrStackFrame frame)
        {
            var reader = GetReaderForFrame(frame);

            if (reader != null)
            {
                var method = frame.Method;

                var result = reader.GetMethod((int)method.MetadataToken, out ISymUnmanagedMethod methodSym);
                if (methodSym != null)
                {
                    var seqPoints = methodSym.GetSequencePoints();
                    var ilOffset  = FindIlOffset(frame);
                    if (ilOffset >= 0)
                    {
                        var nearest = FindNearestLine(seqPoints, ilOffset);
                        if (nearest.Line == PdbHiddenLine)
                        {
                            nearest.Line = 0;
                        }

                        _logger?.LogTrace("FindNearestLine for {0} in method {1} returning {2} in {3}", ilOffset, method.Name, nearest.Line, nearest.File);
                        return(nearest);
                    }
                }
            }

            return(default(FileAndLineNumber));
        }
Пример #12
0
 public ClrStackRoot(ulong address, ClrObject obj, ClrStackFrame stackFrame, bool interior, bool pinned)
 {
     Address    = address;
     Object     = obj;
     StackFrame = stackFrame;
     IsInterior = interior;
     IsPinned   = pinned;
 }
Пример #13
0
        public StackFrame(ClrStackFrame frame)
        {
            var signature = frame.Method?.Signature;

            Text      = string.IsNullOrEmpty(signature) ? "?" : string.Intern(signature);
            Signature = new List <string>();
            ComputeNames(frame);
        }
Пример #14
0
 public ThreadStackFrame(ClrStackFrame clrStackFrame)
 {
     if (clrStackFrame.Method != null)
     {
         Method = new MethodRef(clrStackFrame.Method);
     }
     DisplayName = clrStackFrame.DisplayString;
 }
Пример #15
0
        private string GetFrameInformation(ClrThread thread, ClrStackFrame frame, ClrStackFrame firstFrame)
        {
            // get the method call from the given frame
            string info           = "";
            var    sourceLocation = frame.GetFileAndLineNumber();

            if (sourceLocation == null)
            {
                info = frame.DisplayString;
            }
            else  // it seems that GetFileAndLineNumber() does not work --> need to figure out what is the other ClrMD API to dig into the symbols
            {
                info = frame.DisplayString + "[" + sourceLocation.FilePath + ", Line " + sourceLocation.LineNumber.ToString() + "]";
            }

            // look for locking information
            if (firstFrame.Method.Name.Contains("Wait") || (firstFrame.Method.Name == "Enter") && (firstFrame.Method.Type.Name == "System.Threading.Monitor"))
            {
                // special case for MonitorEnter --> not a WaitHandle to wait on
                bool isMonitorEnter = (firstFrame.Method.Name == "Enter") && (firstFrame.Method.Type.Name == "System.Threading.Monitor");

                info = info + "\r\n                             => " + firstFrame.Method.Type.Name + "." + firstFrame.Method.Name;

                // look for object used as lock
                int maxStackObjects = 10;
                foreach (var so in thread.EnumerateStackObjects(true))
                {
                    if (so == null)
                    {
                        continue;
                    }

                    var type = so.Type;
                    if (so.Type == null)
                    {
                        continue;
                    }

                    string typeName = so.Type.Name;
                    if (typeName.Contains("WaitHandle") || isMonitorEnter)
                    {
                        info = info + string.Format("({0} = 0x{1:X16})\r\n", typeName, so.Object);
                        break;
                    }
                    else
                    {
                    }

                    maxStackObjects--;
                    if (maxStackObjects == 0)
                    {
                        break;
                    }
                }
            }

            return(info);
        }
Пример #16
0
        public ClrStackFrameCloneable(ClrStackFrame actual)
        {
            if (null == actual)
            {
                throw new ArgumentNullException("actual");
            }

            m_actual = actual;
        } // end constructor
Пример #17
0
        public ClrStackInteriorRoot(ClrSegment seg, ulong address, ulong objAddr, ClrStackFrame stackFrame, bool pinned)
        {
            _segment      = seg;
            ObjectPointer = objAddr;

            Address    = address;
            StackFrame = stackFrame;
            IsPinned   = pinned;
        }
Пример #18
0
 private static StackFrameInfo GetStackFrameInfo(ClrStackFrame frame)
 {
     return
         (new StackFrameInfo
     {
         StackPointer = frame.StackPointer,
         InstructionPointer = frame.InstructionPointer,
         DisplayString = frame.DisplayString
     });
 }
Пример #19
0
        public StackFrame(ClrStackFrame frame)
        {
#if ClrMD1
            Text = string.Intern(frame.DisplayString);
#else
            var signature = frame.Method?.Signature;
            Text = string.IsNullOrEmpty(signature) ? "?" : string.Intern(signature);
#endif
            Signature = new List <string>();
            ComputeNames(frame);
        }
Пример #20
0
 public LocalVarRoot(ulong addr, ulong obj, ClrType type, ClrAppDomain domain, ClrThread thread, bool pinned, bool falsePos, bool interior, ClrStackFrame stackFrame)
 {
     Address     = addr;
     Object      = obj;
     _pinned     = pinned;
     _falsePos   = falsePos;
     _interior   = interior;
     _domain     = domain;
     _thread     = thread;
     _type       = type;
     _stackFrame = stackFrame;
 }
Пример #21
0
 public LocalVarRoot(ulong addr, ulong obj, ClrType type, ClrAppDomain domain, ClrThread thread, bool pinned, bool falsePos, bool interior, ClrStackFrame stackFrame)
 {
     Address  = addr;
     Object   = obj;
     IsPinned = pinned;
     IsPossibleFalsePositive = falsePos;
     IsInterior = interior;
     AppDomain  = domain;
     Thread     = thread;
     Type       = type;
     StackFrame = stackFrame;
 }
Пример #22
0
        private ISymUnmanagedReader GetReaderForFrame(ClrStackFrame frame)
        {
            ClrModule           module = frame.Method?.Type?.Module;
            PdbInfo             info   = module?.Pdb;
            ISymUnmanagedReader reader = null;
            string name = string.Empty;

            if (info != null)
            {
                if (_pdbReaders.TryGetValue(info, out reader))
                {
                    return(reader);
                }

                name = Path.GetFileName(info.FileName);
                if (!File.Exists(name))
                {
                    _logger?.LogTrace("Symbol file {0} missing", name);
                    return(null);
                }

                try
                {
                    Stream stream = File.OpenRead(name);
                    if (IsPortablePdb(stream))
                    {
                        var bindar = new SymBinder();
                        int result = bindar.GetReaderFromPdbFile(new MetaDataImportProvider(module.MetadataImport), name, out reader);
                    }
                    else
                    {
                        reader = SymUnmanagedReaderFactory.CreateReaderWithMetadataImport <ISymUnmanagedReader3>(stream, module.MetadataImport, SymUnmanagedReaderCreationOptions.Default);
                    }
                }
                catch (Exception e)
                {
                    _logger?.LogError(e, "Unable to obtain symbol reader for {0}", name);
                }
            }

            if (reader != null)
            {
                _logger?.LogTrace("Symbol file {0} found, reader created", name);
                _pdbReaders.Add(info, reader);
            }
            else
            {
                _logger?.LogTrace("Unable to obtain symbol reader for {0}", name);
            }

            return(reader);
        }
Пример #23
0
        public static FileAndLineNumber FileAndLineNumber(this ClrStackFrame frame)
        {
            PdbReader reader = GetReaderForFrame(frame);

            if (reader == null)
            {
                return(new FileAndLineNumber());
            }

            PdbFunction function = reader.GetFunctionFromToken(frame.Method.MetadataToken);
            int         ilOffset = FindIlOffset(frame);

            return(FindNearestLine(function, ilOffset));
        }
Пример #24
0
        public static SourceLocation GetSourceLocation(this ClrStackFrame frame)
        {
            PdbReader reader = GetReaderForMethod(frame.Method);

            if (reader == null)
            {
                return(null);
            }

            PdbFunction function = reader.GetFunctionFromToken(frame.Method.MetadataToken);
            int         ilOffset = FindIlOffset(frame);

            return(FindNearestLine(function, ilOffset));
        }
        public StackFrameInformation(ClrDump clrDump, ClrStackFrame frame)
        {
            this.clrDump  = clrDump;
            this.frame    = frame;
            DisplayString = frame.DisplayString;
            Kind          = frame.Kind;
            Method        = frame.Method;

#if LINE_AND_FILE
            if (frame.Kind != ClrStackFrameType.Runtime)
            {
                fileAndLineNumber = clrDump.Eval(() => frame.FileAndLineNumber());
            }
#endif
        }
Пример #26
0
        private string GetFrameInformation(ClrThread thread, ClrStackFrame frame, ClrStackFrame firstFrame)
        {
            // get the method call from the given frame
            string info = frame.DisplayString;

            // look for locking information
            if (firstFrame.Method.Name.Contains("Wait") || (firstFrame.Method.Name == "Enter") && (firstFrame.Method.Type.Name == "System.Threading.Monitor"))
            {
                // special case for MonitorEnter --> not a WaitHandle to wait on
                bool isMonitorEnter = (firstFrame.Method.Name == "Enter") && (firstFrame.Method.Type.Name == "System.Threading.Monitor");

                info = info + "\r\n                             => " + firstFrame.Method.Type.Name + "." + firstFrame.Method.Name;

                // look for object used as lock
                int maxStackObjects = 10;
                foreach (var so in thread.EnumerateStackObjects(true))
                {
                    if (so == null)
                    {
                        continue;
                    }

                    var type = so.Type;
                    if (so.Type == null)
                    {
                        continue;
                    }

                    string typeName = so.Type.Name;
                    if (typeName.Contains("WaitHandle") || isMonitorEnter)
                    {
                        info = info + string.Format("({0} = 0x{1:X16})\r\n", typeName, so.Object);
                        break;
                    }
                    else
                    {
                    }

                    maxStackObjects--;
                    if (maxStackObjects == 0)
                    {
                        break;
                    }
                }
            }

            return(info);
        }
Пример #27
0
        public int Next(out ulong pIP, out ulong pSP, out string pFunction)
        {
            if (m_curr < m_frames.Count)
            {
                ClrStackFrame frame = m_frames[m_curr];
                pIP       = frame.InstructionPointer;
                pSP       = frame.StackPointer;
                pFunction = frame.ToString();
                return(HRESULTS.S_OK);
            }

            m_curr++;
            pIP       = 0;
            pSP       = 0;
            pFunction = null;
            return((m_curr == m_frames.Count) ? HRESULTS.S_FALSE : HRESULTS.E_FAIL);
        }
Пример #28
0
        private IEnumerable <ClrRoot> EnumerateStackReferencesWorker(ClrThread thread)
        {
            using (SOSStackRefEnum stackRefEnum = _sos.EnumerateStackRefs(thread.OSThreadId))
            {
                if (stackRefEnum == null)
                {
                    yield break;
                }

                ClrAppDomain   domain = GetAppDomainByAddress(thread.AppDomain);
                ClrHeap        heap   = Heap;
                StackRefData[] refs   = new StackRefData[1024];

                const int GCInteriorFlag = 1;
                const int GCPinnedFlag   = 2;
                int       fetched        = 0;
                while ((fetched = stackRefEnum.ReadStackReferences(refs)) != 0)
                {
                    for (uint i = 0; i < fetched && i < refs.Length; ++i)
                    {
                        if (refs[i].Object == 0)
                        {
                            continue;
                        }

                        bool pinned   = (refs[i].Flags & GCPinnedFlag) == GCPinnedFlag;
                        bool interior = (refs[i].Flags & GCInteriorFlag) == GCInteriorFlag;

                        ClrType type = null;

                        if (!interior)
                        {
                            type = heap.GetObjectType(refs[i].Object);
                        }

                        ClrStackFrame frame = thread.StackTrace.SingleOrDefault(
                            f => f.StackPointer == refs[i].Source || f.StackPointer == refs[i].StackPointer && f.InstructionPointer == refs[i].Source);

                        if (interior || type != null)
                        {
                            yield return(new LocalVarRoot(refs[i].Address, refs[i].Object, type, domain, thread, pinned, false, interior, frame));
                        }
                    }
                }
            }
        }
Пример #29
0
        internal DbgStackFrameInfo(DbgEngDebugger debugger,
                                   DbgUModeThreadInfo thread,
                                   DEBUG_STACK_FRAME_EX nativeFrame,
                                   ClrStackFrame managedFrame,
                                   bool alreadySearchManagedFrames)
            : base(debugger)
        {
            if (null == thread)
            {
                throw new ArgumentNullException("thread");
            }

            NativeFrameEx  = nativeFrame;
            Thread         = thread;
            m_managedFrame = managedFrame;
            m_alreadySearchedManagedFrames = alreadySearchManagedFrames;
        } // end constructor()
Пример #30
0
        public static SDFileAndLineNumber GetSourceLocation(this ClrStackFrame frame)
        {
            try {
                PdbReader reader = GetReaderForFrame(frame);
                if (reader == null)
                {
                    return(null);
                }

                PdbFunction function = reader.GetFunctionFromToken(frame.Method.MetadataToken);
                int         ilOffset = FindIlOffset(frame);

                return(FindNearestLine(function, ilOffset));
            } catch (Exception e) {
                Console.WriteLine($"exception in {nameof(GetSourceLocation)}: {e}");
                return(null);
            }
        }