Beispiel #1
0
 public NativeStackRootWalker(ClrHeap heap, ClrAppDomain domain, ClrThread thread)
 {
     _heap = heap;
     _domain = domain;
     _thread = thread;
     Roots = new List<ClrRoot>();
 }
Beispiel #2
0
 public RhStackRootWalker(ClrHeap heap, ClrAppDomain domain, ClrThread thread)
 {
     m_heap = heap;
     m_domain = domain;
     m_thread = thread;
     Roots = new List<ClrRoot>();
 }
Beispiel #3
0
        internal override IEnumerable<ClrRoot> EnumerateStackReferences(ClrThread thread, bool includeDead)
        {
            if (includeDead)
                return base.EnumerateStackReferences(thread, includeDead);

            return EnumerateStackReferencesWorker(thread);
        }
Beispiel #4
0
        IEnumerable<ClrRoot> EnumerateStackReferencesWorker(ClrThread thread)
        {
            ISOSStackRefEnum handleEnum = null;
            object tmp;
            if (m_sos.GetStackReferences(thread.OSThreadId, out tmp) >= 0)
                handleEnum = tmp as ISOSStackRefEnum;

            ClrAppDomain domain = GetAppDomainByAddress(thread.AppDomain);
            if (handleEnum != null)
            {
                var heap = GetHeap();
                StackRefData[] refs = new StackRefData[1024];

                const int GCInteriorFlag = 1;
                const int GCPinnedFlag = 2;
                uint fetched = 0;
                do
                {
                    if (handleEnum.Next((uint)refs.Length, refs, out fetched) < 0)
                        break;

                    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);

                        if (interior || type != null)
                            yield return new LocalVarRoot(refs[i].Address, refs[i].Object, type, domain, thread, pinned, false, interior);
                    }
                } while (fetched == refs.Length);
            }
        }
        private string GetBlockingObjectsIfAny(ClrThread thread)
        {
            var blockingObjects = thread.BlockingObjects;

            if (blockingObjects == null)
            {
                return("");
            }

            StringBuilder sb = new StringBuilder();

            foreach (var blockinObject in thread.BlockingObjects)
            {
                sb.Append(blockinObject.Reason);
                if (blockinObject.HasSingleOwner)
                {
                    sb.AppendFormat("waiting for {0} on 0x{1}", blockinObject.Owner.ManagedThreadId, blockinObject.Object.ToString("X16"));
                }
                else
                {
                    sb.AppendFormat("waiting for ");
                    int last    = blockinObject.Owners.Count - 1;
                    int current = 0;
                    foreach (var ownerThread in blockinObject.Owners)
                    {
                        if (current == last)
                        {
                            sb.AppendFormat("{0}", ownerThread.ManagedThreadId);
                        }
                        else
                        {
                            sb.AppendFormat("{0} | ", ownerThread.ManagedThreadId);
                        }
                    }
                    sb.AppendFormat(" on 0x{0}", blockinObject.Object.ToString("X16"));
                }
            }

            return(sb.ToString());
        }
Beispiel #6
0
        private void DisplayChainForThreadAux(ClrThread thread, int depth, HashSet <int> visitedThreadIds)
        {
            _context.WriteLink(
                String.Format("{0}+ Thread {1}", new string(' ', depth * 2), thread.ManagedThreadId),
                String.Format("~ {0}; !clrstack", thread.ManagedThreadId));
            _context.WriteLine();

            if (visitedThreadIds.Contains(thread.ManagedThreadId))
            {
                _context.WriteLine("{0}*** DEADLOCK!", new string(' ', depth * 2));
                return;
            }
            visitedThreadIds.Add(thread.ManagedThreadId);

            foreach (var blockingObject in thread.BlockingObjects)
            {
                _context.Write("{0}| {1} ", new string(' ', (depth + 1) * 2), blockingObject.Reason);
                var type = _context.Heap.GetObjectType(blockingObject.Object);
                if (type != null && !String.IsNullOrEmpty(type.Name))
                {
                    _context.WriteLink(
                        String.Format("{0:x16} {1}", blockingObject.Object, type.Name),
                        String.Format("!do {0:x16}", blockingObject.Object));
                }
                else
                {
                    _context.Write("{0:x16}", blockingObject.Object);
                }
                _context.WriteLine();
                foreach (var owner in blockingObject.Owners)
                {
                    if (owner == null) // ClrMD sometimes reports this nonsense
                    {
                        continue;
                    }

                    DisplayChainForThreadAux(owner, depth + 2, visitedThreadIds);
                }
            }
        }
Beispiel #7
0
        private void FindDeadlockStartingFrom(ClrThread thread, HashSet <uint> visitedThreadIds, Stack <string> chain)
        {
            if (thread == null)
            {
                return;
            }

            if (visitedThreadIds.Contains(thread.OSThreadId))
            {
                WriteTraceLine("Deadlock found between the following threads:");
                foreach (var entry in chain.Reverse())
                {
                    WriteTraceLine($"  {entry} -->");
                }
                WriteTraceLine($"  Thread {thread.OSThreadId}, DEADLOCK!");
                return;
            }

            visitedThreadIds.Add(thread.OSThreadId);
            string topStackTrace = String.Join("\n      ",
                                               thread.StackTrace.Where(f => f.Kind == ClrStackFrameType.ManagedMethod)
                                               .Select(f => f.DisplayString)
                                               .Take(5));

            chain.Push($"Thread {thread.OSThreadId} at {topStackTrace}");

            foreach (var blockingObject in thread.BlockingObjects)
            {
                chain.Push($"{blockingObject.Reason} at {blockingObject.Object:X}");
                foreach (var owner in blockingObject.Owners)
                {
                    FindDeadlockStartingFrom(owner, visitedThreadIds, chain);
                }
                chain.Pop();
            }

            chain.Pop();
            visitedThreadIds.Remove(thread.OSThreadId);
        }
Beispiel #8
0
        public void VariableRootTest()
        {
            // Test to make sure that a specific static and local variable exist.

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

                var fooRoots = from root in heap.EnumerateRoots()
                               where root.Type.Name == "Foo"
                               select root;

                ClrRoot staticRoot = fooRoots.Where(r => r.Kind == GCRootKind.StaticVar).Single();
                Assert.IsTrue(staticRoot.Name.Contains("s_foo"));

                var     arr          = fooRoots.Where(r => r.Kind == GCRootKind.LocalVar).ToArray();
                ClrRoot localVarRoot = fooRoots.Where(r => r.Kind == GCRootKind.LocalVar).Single();

                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;
                }


                Assert.IsTrue(low <= localVarRoot.Address && localVarRoot.Address <= high);
            }
        }
Beispiel #9
0
        private Tuple <ulong, int, ulong, uint, uint>[] GetClrStackFrameLocals(Tuple <int, uint, int> input)
        {
            int              runtimeId      = input.Item1;
            uint             threadSystemId = input.Item2;
            int              stackFrameId   = input.Item3;
            ClrRuntime       clrRuntime     = runtimesCache[runtimeId];
            ClrThread        clrThread      = clrRuntime.Threads.First(t => t.OSThreadId == threadSystemId);
            ClrStackFrame    clrStackFrame  = clrThread.StackTrace[stackFrameId];
            IList <ClrValue> clrValues      = clrStackFrame.Locals;

            Tuple <ulong, int, ulong, uint, uint>[] variables = new Tuple <ulong, int, ulong, uint, uint> [clrValues.Count];
            ulong moduleBase    = clrStackFrame.Module.ImageBase;
            uint  metadataToken = clrStackFrame.Method.MetadataToken;
            uint  ilOffset      = FindIlOffset(clrStackFrame);

            for (int i = 0; i < variables.Length; i++)
            {
                GetClrValueAddressAndCodeTypeId(clrValues[i], out ulong address, out int codeTypeId);
                variables[i] = Tuple.Create(address, codeTypeId, moduleBase, metadataToken, ilOffset);
            }
            return(variables);
        }
Beispiel #10
0
        public void PdbSourceLineTest()
        {
            using (DataTarget dt = TestTargets.NestedException.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
                ClrThread  thread  = runtime.GetMainThread();

                HashSet <int> sourceLines = new HashSet <int>();
                using (PdbReader reader = new PdbReader(TestTargets.NestedException.Pdb))
                {
                    Assert.IsTrue(TestTargets.NestedException.Source.Equals(reader.Sources.Single().Name, StringComparison.OrdinalIgnoreCase));

                    var functions = from frame in thread.StackTrace
                                    where frame.Kind != ClrStackFrameType.Runtime
                                    select reader.GetFunctionFromToken(frame.Method.MetadataToken);

                    foreach (PdbFunction function in functions)
                    {
                        PdbSequencePointCollection sourceFile = function.SequencePoints.Single();

                        foreach (int line in sourceFile.Lines.Select(l => l.LineBegin))
                        {
                            sourceLines.Add(line);
                        }
                    }
                }


                int curr = 0;
                foreach (var line in File.ReadLines(TestTargets.NestedException.Source))
                {
                    curr++;
                    if (line.Contains("/* seq */"))
                    {
                        Assert.IsTrue(sourceLines.Contains(curr));
                    }
                }
            }
        }
Beispiel #11
0
        public void PrimitiveVariableConversionTest()
        {
            ClrThread  clrThread = Thread.Current.FindClrThread();
            StackFrame frame;

            foreach (var f in clrThread.ClrStackTrace.Frames)
            {
                foreach (var variable in f.Locals)
                {
                    System.Console.WriteLine(" {2} = ({0}) {1:X}", variable.GetCodeType(), variable.GetPointerAddress(), variable.GetName());
                }
            }

            foreach (Variable variable in clrThread.EnumerateStackObjects())
            {
                System.Console.WriteLine("   ({0}) {1:X}", variable.GetCodeType(), variable.GetPointerAddress());
            }

            frame = clrThread.ClrStackTrace.Frames.Where(f => f.FunctionNameWithoutModule.StartsWith("Program.Inner(")).Single();
            Assert.IsTrue((bool)frame.Locals["b"]);
            Assert.AreEqual('c', (char)frame.Locals["c"]);
            Assert.AreEqual("hello world", new ClrString(frame.Locals["s"]).Text);
            Assert.AreEqual(42, (int)frame.Locals["st"].GetField("i"));
            Assert.IsTrue(clrThread.EnumerateStackObjects().Contains(frame.Locals["s"]));

            frame = clrThread.ClrStackTrace.Frames.Where(f => f.FunctionNameWithoutModule.StartsWith("Program.Middle(")).Single();
            Assert.AreEqual(0x42, (byte)frame.Locals["b"]);
            Assert.AreEqual(0x43, (sbyte)frame.Locals["sb"]);
            Assert.AreEqual(0x4242, (short)frame.Locals["sh"]);
            Assert.AreEqual(0x4243, (ushort)frame.Locals["ush"]);
            Assert.AreEqual(0x42424242, (int)frame.Locals["i"]);
            Assert.AreEqual(0x42424243u, (uint)frame.Locals["ui"]);

            frame = clrThread.ClrStackTrace.Frames.Where(f => f.FunctionNameWithoutModule.StartsWith("Program.Outer(")).Single();
            Assert.AreEqual(42.0f, (float)frame.Locals["f"]);
            Assert.AreEqual(43.0, (double)frame.Locals["d"]);
            Assert.AreEqual((ulong)0x42424242, (ulong)frame.Locals["ptr"]);
            Assert.AreEqual((ulong)0x43434343, (ulong)frame.Locals["uptr"]);
        }
Beispiel #12
0
        private void UpdateWithLockInfo(ClrThread thread, ThreadInfo info)
        {
            var locks = thread.BlockingObjects;

            if (locks != null)
            {
                foreach (var lck in locks)
                {
                    if (lck.Taken)
                    {
                        var lockClass = thread.Runtime.Heap.GetObjectType(lck.Object);
                        if (lockClass != null)
                        {
                            LockInfo lockInfo = null;
                            if (lck.Reason == BlockingReason.Monitor ||
                                lck.Reason == BlockingReason.MonitorWait)
                            {
                                lockInfo = new MonitorInfo();
                            }
                            else
                            {
                                lockInfo = new LockInfo();
                            }

                            lockInfo.ClassName        = lockClass.Name;
                            lockInfo.IdentityHashCode = (int)lck.Object;

                            info.LockInfo      = lockInfo;
                            info.LockName      = lockInfo.ClassName + "@" + string.Format("{0:X}", lck.Object);
                            info.LockOwnerId   = lck.HasSingleOwner && lck.Owner != null ? lck.Owner.ManagedThreadId : -1;
                            info.LockOwnerName = lck.HasSingleOwner && lck.Owner != null?GetThreadName(lck.Owner) : "Unknown";
                        }
                    }
                }
            }

            _logger?.LogTrace("Updated threads lock info");
        }
Beispiel #13
0
        /// <summary>
        /// Inits the thread dictionary with OS ID and engine ID of every thread,
        /// and also refs managed thread if there is one for each thread in the process dump
        /// </summary>
        private void InitAllThreadIds()
        {
            // get amount of threads in the process
            Utility.CheckHRESULT(((IDebugSystemObjects)this.debugClient).GetNumberThreads(out numberOfThreads));

            for (uint i = 0; i < numberOfThreads; i++)
            {
                var engineThreadIds = new uint[1];             // has to be array, see IDebugSystemObjects.GetThreadIdsByIndex
                var osThreadIds     = new uint[1];             // same here

                // get the engine id(s) and also the os id(s) of each thread
                Utility.CheckHRESULT(((IDebugSystemObjects)this.debugClient).GetThreadIdsByIndex(i, 1, engineThreadIds, osThreadIds));

                // create new SDThread object and add it to the dictionary
                var t = new SDThread(i);
                t.OsId     = osThreadIds[0];
                t.EngineId = engineThreadIds[0];

                ClrThread managedThread = null;
                if (context.Runtime != null)
                {
                    managedThread = context.Runtime.Threads.FirstOrDefault(thread => thread.OSThreadId == t.OsId);
                    if (managedThread != null)
                    {
                        t.IsManagedThread    = true;
                        t.ManagedThreadId    = managedThread.ManagedThreadId;
                        t.State              = managedThread.SpecialDescription();
                        t.IsThreadPoolThread = managedThread.IsThreadPoolThread();
                    }
                    else
                    {
                        t.IsManagedThread = false;
                    }
                }

                this.threads.Add(t.OsId, t);
            }
        }
        public ThreadInformation(ClrDump clrDump, ClrThread thread)
        {
            ClrDump = clrDump;
            Thread  = thread;

            clrDump.Run(() =>
            {
                OSThreadId       = thread.OSThreadId;
                ManagedThreadId  = thread.ManagedThreadId;
                CurrentException = thread.CurrentException?.Type?.Name;
                GcMode           = thread.GcMode;
                IsAborted        = thread.IsAborted;
                IsAbortRequested = thread.IsAbortRequested;
                IsAlive          = thread.IsAlive;

                IsBackground               = thread.IsBackground;
                IsCoInitialized            = thread.IsCoInitialized;
                IsDebuggerHelper           = thread.IsDebuggerHelper;
                IsDebugSuspended           = thread.IsDebugSuspended;
                IsFinalizer                = thread.IsFinalizer;
                IsGC                       = thread.IsGC;
                IsGCSuspendPending         = thread.IsGCSuspendPending;
                IsMTA                      = thread.IsMTA;
                IsShutdownHelper           = thread.IsShutdownHelper;
                IsSTA                      = thread.IsSTA;
                IsSuspendingEE             = thread.IsSuspendingEE;
                IsThreadpoolCompletionPort = thread.IsThreadpoolCompletionPort;
                IsThreadpoolGate           = thread.IsThreadpoolGate;
                IsThreadpoolTimer          = thread.IsThreadpoolTimer;
                IsThreadpoolWait           = thread.IsThreadpoolWait;
                IsThreadpoolWorker         = thread.IsThreadpoolWorker;
                IsUnstarted                = thread.IsUnstarted;
                IsUserSuspended            = thread.IsUserSuspended;
                LockCount                  = thread.LockCount;
                var gcThreads              = clrDump.Runtime.EnumerateGCThreads().ToList();
                IsGCThread                 = gcThreads.Any(gcThreadId => gcThreadId == OSThreadId);
            });
        }
Beispiel #15
0
        public void MinidumpCallstackTest()
        {
            using DataTarget dt      = TestTargets.NestedException.LoadMiniDump();
            using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
            ClrThread thread = runtime.GetMainThread();

            string[] frames = IntPtr.Size == 8 ? new[] { "Inner", "Inner", "Middle", "Outer", "Main" } : new[] { "Inner", "Middle", "Outer", "Main" };

            int i = 0;

            foreach (ClrStackFrame frame in thread.EnumerateStackTrace())
            {
                if (frame.Kind == ClrStackFrameKind.ManagedMethod)
                {
                    Assert.NotEqual(0ul, frame.InstructionPointer);
                    Assert.NotEqual(0ul, frame.StackPointer);
                    Assert.NotNull(frame.Method);
                    Assert.NotNull(frame.Method.Type);
                    Assert.NotNull(frame.Method.Type.Module);
                    Assert.Equal(frames[i++], frame.Method.Name);
                }
            }
        }
Beispiel #16
0
        private List<LockInfo> GetThisThreadsLockedSyncronizers(ClrThread thread, IList<BlockingObject> allLocks)
        {
            List<LockInfo> result = new List<LockInfo>();
            foreach (var lck in allLocks)
            {
                if (lck.Reason != BlockingReason.Monitor && lck.Reason != BlockingReason.MonitorWait && thread.Address == lck.Owner?.Address)
                {
                    var lockClass = thread.Runtime.Heap.GetObjectType(lck.Object);
                    if (lockClass != null)
                    {
                        LockInfo info = new LockInfo()
                        {
                            ClassName = lockClass.Name,
                            IdentityHashCode = (int)lck.Object
                        };
                        result.Add(info);
                    }
                }
            }

            _logger?.LogTrace("Thread has {0} non monitor locks", result.Count);
            return result;
        }
Beispiel #17
0
        private static void DumpThreadInfo(ClrThread thread, TextWriter writer)
        {
            writer.WriteLine($"Thread #{thread.ManagedThreadId}");
            writer.WriteLine($"  OS Thread ID:      {thread.OSThreadId}");
            writer.WriteLine($"  AppDomain Address: {thread.CurrentAppDomain.Address}");

            var type = thread.IsBackground ? "Background" : "Foreground";

            writer.WriteLine($"  Type:              {type}");

            if (thread.IsAbortRequested)
            {
                writer.WriteLine($"  IsAbortRequested:  {thread.IsAbortRequested}");
            }

            var roles = new List <string>();

            if (thread.IsFinalizer)
            {
                roles.Add("Finalizer");
            }

            /*if (thread.IsDebuggerHelper) roles.Add("Debugger Helper");
             * if (thread.IsGC) roles.Add("GC Thread");
             * if (thread.IsShutdownHelper) roles.Add("Shutdown Helper");
             *
             * if (thread.IsThreadpoolCompletionPort) roles.Add("Threadpool I/O Completion Port");
             * if (thread.IsThreadpoolGate) roles.Add("Threadpool Gate");
             * if (thread.IsThreadpoolTimer) roles.Add("Threadpool Timer");
             * if (thread.IsThreadpoolWait) roles.Add("Threadpool Wait");
             * if (thread.IsThreadpoolWorker) roles.Add("Threadpool Worker");*/

            if (roles.Count > 0)
            {
                writer.WriteLine($"  Role:              {String.Join(", ", roles)}");
            }
        }
Beispiel #18
0
        public override object GetValue(ClrAppDomain appDomain, ClrThread thread, bool convertStrings = true)
        {
            if (!HasSimpleValue)
                return null;

            Address addr = GetAddress(appDomain, thread);
            if (addr == 0)
                return null;

            if (ElementType == ClrElementType.String)
            {
                object val = _type.DesktopHeap.GetValueAtAddress(ClrElementType.Object, addr);

                Debug.Assert(val == null || val is ulong);
                if (val == null || !(val is ulong))
                    return convertStrings ? null : (object)(ulong)0;

                addr = (ulong)val;
                if (!convertStrings)
                    return addr;
            }

            return _type.DesktopHeap.GetValueAtAddress(ElementType, addr);
        }
Beispiel #19
0
        private List <StackTraceElement> GetStackTrace(ClrThread thread)
        {
            List <StackTraceElement> result = new List <StackTraceElement>();

            _logger?.LogTrace("Starting stack dump for thread");

            if (thread.IsAlive)
            {
                var stackTrace = thread.StackTrace;
                if (stackTrace != null)
                {
                    foreach (ClrStackFrame frame in stackTrace)
                    {
                        StackTraceElement element = GetStackTraceElement(frame);
                        if (element != null)
                        {
                            result.Add(element);
                        }
                    }
                }
            }

            return(result);
        }
Beispiel #20
0
        private List <MonitorInfo> GetThisThreadsLockedMonitors(ClrThread thread, IList <BlockingObject> allLocks)
        {
            var result = new List <MonitorInfo>();

            foreach (var lck in allLocks)
            {
                if ((lck.Reason == BlockingReason.Monitor || lck.Reason == BlockingReason.MonitorWait) && thread.Address == lck.Owner?.Address)
                {
                    var lockClass = thread.Runtime.Heap.GetObjectType(lck.Object);
                    if (lockClass != null)
                    {
                        var info = new MonitorInfo()
                        {
                            ClassName        = lockClass.Name,
                            IdentityHashCode = (int)lck.Object
                        };
                        result.Add(info);
                    }
                }
            }

            _logger?.LogTrace("Thread has {0} monitor locks", result.Count);
            return(result);
        }
Beispiel #21
0
 public static string SpecialDescription(this ClrThread thread)
 {
     if (thread.IsDebuggerHelper)
     {
         return("DbgHelper");
     }
     if (thread.IsFinalizer)
     {
         return("Finalizer");
     }
     if (thread.IsGC)
     {
         return("GC");
     }
     if (thread.IsShutdownHelper)
     {
         return("ShutdownHelper");
     }
     if (thread.IsAborted)
     {
         return("Aborted");
     }
     if (thread.IsAbortRequested)
     {
         return("AbortRequested");
     }
     if (thread.IsUnstarted)
     {
         return("Unstarted");
     }
     if (thread.IsUserSuspended)
     {
         return("Suspended");
     }
     return("");
 }
Beispiel #22
0
        public static void WriteStackTraceToContext(this ClrThread thread, IList <ClrStackFrame> stackTrace, CommandExecutionContext context, bool displayArgumentsAndLocals)
        {
            FrameArgumentsAndLocals[] argsAndLocals = displayArgumentsAndLocals ?
                                                      new FrameArgumentsAndLocalsRetriever(thread, stackTrace, context).ArgsAndLocals :
                                                      new FrameArgumentsAndLocals[0];

            context.WriteLine("{0,-20} {1,-20} {2}", "SP", "IP", "Function");
            foreach (var frame in stackTrace)
            {
                var sourceLocation = context.SymbolCache.GetFileAndLineNumberSafe(frame);
                context.WriteLine("{0,-20:X16} {1,-20:X16} {2} {3}",
                                  frame.StackPointer, frame.InstructionPointer,
                                  frame.DisplayString,
                                  sourceLocation == null ? "" : String.Format("[{0}:{1},{2}]", sourceLocation.FilePath, sourceLocation.LineNumber, sourceLocation.ColStart));

                var frameArgsAndLocals = argsAndLocals.FirstOrDefault(
                    al => al.MethodName == frame.DisplayString);
                if (frameArgsAndLocals != null)
                {
                    frameArgsAndLocals.Arguments.ForEach(a => DisplayOneArgumentOrLocal(context, "arg", a));
                    frameArgsAndLocals.LocalVariables.ForEach(l => DisplayOneArgumentOrLocal(context, "lcl", l));
                }
            }
        }
Beispiel #23
0
        ClrDacThreadInfo CreateClrDacThreadInfo(ClrThread thread)
        {
            var flags = ClrDacThreadFlags.None;

            if (thread.IsFinalizer)
            {
                flags |= ClrDacThreadFlags.IsFinalizer;
            }
            if (thread.IsAlive)
            {
                flags |= ClrDacThreadFlags.IsAlive;
            }
            if (clrRuntime.ServerGC && thread.IsGC)
            {
                flags |= ClrDacThreadFlags.IsGC;
            }
            if (thread.IsDebuggerHelper)
            {
                flags |= ClrDacThreadFlags.IsDebuggerHelper;
            }
            if (thread.IsThreadpoolTimer)
            {
                flags |= ClrDacThreadFlags.IsThreadpoolTimer;
            }
            if (thread.IsThreadpoolCompletionPort)
            {
                flags |= ClrDacThreadFlags.IsThreadpoolCompletionPort;
            }
            if (thread.IsThreadpoolWorker)
            {
                flags |= ClrDacThreadFlags.IsThreadpoolWorker;
            }
            if (thread.IsThreadpoolWait)
            {
                flags |= ClrDacThreadFlags.IsThreadpoolWait;
            }
            if (thread.IsThreadpoolGate)
            {
                flags |= ClrDacThreadFlags.IsThreadpoolGate;
            }
            if (thread.IsSuspendingEE)
            {
                flags |= ClrDacThreadFlags.IsSuspendingEE;
            }
            if (thread.IsShutdownHelper)
            {
                flags |= ClrDacThreadFlags.IsShutdownHelper;
            }
            if (thread.IsAbortRequested)
            {
                flags |= ClrDacThreadFlags.IsAbortRequested;
            }
            if (thread.IsAborted)
            {
                flags |= ClrDacThreadFlags.IsAborted;
            }
            if (thread.IsGCSuspendPending)
            {
                flags |= ClrDacThreadFlags.IsGCSuspendPending;
            }
            if (thread.IsUserSuspended)
            {
                flags |= ClrDacThreadFlags.IsUserSuspended;
            }
            if (thread.IsDebugSuspended)
            {
                flags |= ClrDacThreadFlags.IsDebugSuspended;
            }
            if (thread.IsBackground)
            {
                flags |= ClrDacThreadFlags.IsBackground;
            }
            if (thread.IsUnstarted)
            {
                flags |= ClrDacThreadFlags.IsUnstarted;
            }
            if (thread.IsCoInitialized)
            {
                flags |= ClrDacThreadFlags.IsCoInitialized;
            }
            if (thread.IsSTA)
            {
                flags |= ClrDacThreadFlags.IsSTA;
            }
            if (thread.IsMTA)
            {
                flags |= ClrDacThreadFlags.IsMTA;
            }
            return(new ClrDacThreadInfo(thread.ManagedThreadId, flags));
        }
        private bool FindThread(ulong start, ulong stop, out ulong threadAddr, out ClrThread target)
        {
            ClrHeap heap = _runtime.GetHeap();
            foreach (ulong obj in EnumerateObjectsOfType(start, stop, "System.Threading.Thread"))
            {
                ClrType type = heap.GetObjectType(obj);
                ClrInstanceField threadIdField = type.GetFieldByName("m_ManagedThreadId");
                if (threadIdField != null && threadIdField.ElementType == ClrElementType.Int32)
                {
                    int id = (int)threadIdField.GetValue(obj);
                    ClrThread thread = GetThreadById(id);
                    if (thread != null)
                    {
                        threadAddr = obj;
                        target = thread;
                        return true;
                    }
                }
            }

            threadAddr = 0;
            target = null;
            return false;
        }
Beispiel #25
0
 public LocalVarRoot(ulong addr, ulong obj, ClrType type, ClrAppDomain domain, ClrThread thread, bool pinned, bool falsePos, bool interior)
 {
     Address = addr;
     Object = obj;
     _pinned = pinned;
     _falsePos = falsePos;
     _interior = interior;
     _domain = domain;
     _thread = thread;
     _type = type;
 }
Beispiel #26
0
 public static void WriteCurrentExceptionStackTraceToContext(this ClrThread thread, CommandExecutionContext context, bool displayArgumentsAndLocals)
 {
     thread.WriteStackTraceToContext(thread.CurrentException.StackTrace, context, displayArgumentsAndLocals);
 }
Beispiel #27
0
 private bool IsUserSuspended(ClrThread thread)
 {
     _logger?.LogTrace("Thread user suspended {0}", thread.IsUserSuspended);
     return(thread.IsUserSuspended);
 }
Beispiel #28
0
        public override object GetValue(ClrAppDomain appDomain, ClrThread thread)
        {
            if (!HasSimpleValue)
                return null;

            Address addr = GetAddress(appDomain, thread);
            if (addr == 0)
                return null;

            if (ElementType == ClrElementType.String)
            {
                object val = m_type.m_heap.GetValueAtAddress(ClrElementType.Object, addr);

                Debug.Assert(val == null || val is ulong);
                if (val == null || !(val is ulong))
                    return null;

                addr = (ulong)val;
            }

            return m_type.m_heap.GetValueAtAddress(ElementType, addr);
        }
Beispiel #29
0
 public static ClrStackFrame GetFrame(this ClrThread thread, string functionName)
 {
     return(thread.EnumerateStackTrace().Single(sf => sf.Method != null ? sf.Method.Name == functionName : false));
 }
Beispiel #30
0
        public static ClrThread GetMainThread(this ClrRuntime runtime)
        {
            ClrThread thread = runtime.Threads.Single(t => !t.IsBackground);

            return(thread);
        }
 /// <summary>
 /// Gets the address of the field.
 /// </summary>
 /// <param name="appDomain">The AppDomain in which to get the field's address.</param>
 /// <param name="thread">The thread on which to get the field's address.</param>
 /// <returns>The address of the field.</returns>
 public abstract ulong GetAddress(ClrAppDomain appDomain, ClrThread thread);
 /// <summary>
 /// Gets the value of the field.
 /// </summary>
 /// <param name="appDomain">The AppDomain in which to get the field's value.</param>
 /// <param name="thread">The thread on which to get the field's value.</param>
 /// <param name="convertStrings">
 /// When true, the value of a string field will be
 /// returned as a System.String object; otherwise the address of the String object will be returned.
 /// </param>
 /// <returns>The value of the field.</returns>
 public abstract object GetValue(ClrAppDomain appDomain, ClrThread thread, bool convertStrings);
 /// <summary>
 /// Gets the value of the field.
 /// </summary>
 /// <param name="appDomain">The AppDomain in which to get the field's value.</param>
 /// <param name="thread">The thread on which to get the field's value.</param>
 /// <returns>The value of the field.</returns>
 public virtual object GetValue(ClrAppDomain appDomain, ClrThread thread)
 {
     return(GetValue(appDomain, thread, true));
 }
Beispiel #34
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;
 }
Beispiel #35
0
        public override Address GetAddress(ClrAppDomain appDomain, ClrThread thread)
        {
            if (_type == null)
                return 0;

            DesktopRuntimeBase runtime = _type.DesktopHeap.DesktopRuntime;
            IModuleData moduleData = runtime.GetModuleData(_field.Module);

            return runtime.GetThreadStaticPointer(thread.Address, (ClrElementType)_field.CorElementType, (uint)Offset, (uint)moduleData.ModuleId, _type.Shared);
        }
Beispiel #36
0
 private static ThreadInfo ThreadInfoFromThread(ClrThread thread)
 {
     return new ThreadInfo
     {
         OSThreadId = thread.OSThreadId,
         ManagedThreadId = thread.ManagedThreadId
     };
 }
Beispiel #37
0
        private string GetCallStackInfo(ClrMDHelper helper, ClrThread thread)
        {
            // must be a running thread
            if (!thread.IsAlive)
            {
                return("Dead");
            }


            // look for exception first
            var exception = thread.CurrentException;

            if (exception != null)
            {
                return(exception.Type.Name + ": " + exception.Message);
            }

            // try to find some information about where the code is called from
            StringBuilder     sb  = new StringBuilder();
            RunningThreadInfo rti = helper.GetThreadInfo(thread);

            switch (rti.RootType)
            {
            case ThreadRoot.Task:
                sb.Append("Task | " + rti.RootMethod);
                break;

            case ThreadRoot.WorkItem:
                sb.Append("Work | " + rti.RootMethod);
                break;

            default:
                sb.Append("Thread");
                break;
            }

            // add lock related details if any
            if (rti.BlockingDetails != null)
            {
                var bi = rti.BlockingDetails;

                // show the blocking details
                string shortTypeName = "";
                if (bi.ObjRef != 0)
                {
                    ClrType type = _host.Session.Clr.Heap.GetObjectType(bi.ObjRef);
                    if (type != null)
                    {
                        string typeName = type.Name;
                        int    pos      = typeName.LastIndexOf('.');
                        if (pos != -1)
                        {
                            shortTypeName = typeName.Substring(pos + 1);
                        }
                    }
                }
                sb.Append(
                    ((bi.LockingFrame != null) ? "\r\n                                  + " + bi.LockingFrame.DisplayString : "") +
                    "\r\n                                  => " +
                    bi.TypeName + "." + bi.Frame.Method.Name +
                    ((bi.ObjRef != 0) ?
                     "(0x" + bi.ObjRef.ToString("X16") + " : " + shortTypeName + ")" :
                     ""
                    )
                    );
            }

            return(sb.ToString());
        }
Beispiel #38
0
 public static bool IsThreadPoolThread(this ClrThread thread)
 {
     return(thread.IsThreadpoolCompletionPort || thread.IsThreadpoolGate || thread.IsThreadpoolTimer || thread.IsThreadpoolWait || thread.IsThreadpoolWorker);
 }
Beispiel #39
0
 public NativeStackRoot(ClrThread thread, ulong addr, ulong obj, string name, ClrType type, ClrAppDomain domain, bool pinned, bool interior)
 {
     Address = addr;
     Object = obj;
     _name = name;
     _type = type;
     _appDomain = domain;
     _pinned = pinned;
     _interior = interior;
     _thread = thread;
 }
Beispiel #40
0
        internal unsafe IList<ClrRoot> EnumerateStackRoots(ClrThread thread)
        {
            int contextSize;

            var plat = m_dataReader.GetArchitecture();
            if (plat == Architecture.Amd64)
                contextSize = 0x4d0;
            else if (plat == Architecture.X86)
                contextSize = 0x2d0;
            else if (plat == Architecture.Arm)
                contextSize = 0x1a0;
            else
                throw new InvalidOperationException("Unexpected architecture.");
            
            byte[] context = new byte[contextSize];
            m_dataReader.GetThreadContext(thread.OSThreadId, 0, (uint)contextSize, context);

            var walker = new RhStackRootWalker(GetHeap(), GetRhAppDomain(), thread);
            THREADROOTCALLBACK del = new THREADROOTCALLBACK(walker.Callback);
            IntPtr callback = Marshal.GetFunctionPointerForDelegate(del);

            fixed (byte* b = &context[0])
            {
                IntPtr ctx = new IntPtr(b);
                m_sos.TraverseStackRoots(thread.Address, ctx, contextSize, callback, IntPtr.Zero);
            }
            GC.KeepAlive(del);

            return walker.Roots;
        }
Beispiel #41
0
 public static string[] GetStackTraceRepr(this ClrThread thread) =>
 thread.StackTrace
 .Select(frame => frame.DisplayString.EscapeNull())
 .ToArray();
Beispiel #42
0
        public override object GetValue(ClrAppDomain appDomain, ClrThread thread, bool convertStrings = true)
        {
            if (!HasSimpleValue)
                return null;

            Address addr = GetAddress(appDomain, thread);
            if (addr == 0)
                return null;

            if (ElementType == ClrElementType.String)
            {
                object val = _type.DesktopHeap.GetValueAtAddress(ClrElementType.Object, addr);

                Debug.Assert(val == null || val is ulong);
                if (val == null || !(val is ulong))
                    return convertStrings ? null : (object)(ulong)0;

                addr = (ulong)val;
                if (!convertStrings)
                    return addr;
            }

            return _type.DesktopHeap.GetValueAtAddress(ElementType, addr);
        }