public NativeStackRootWalker(ClrHeap heap, ClrAppDomain domain, ClrThread thread) { _heap = heap; _domain = domain; _thread = thread; Roots = new List<ClrRoot>(); }
public RhStackRootWalker(ClrHeap heap, ClrAppDomain domain, ClrThread thread) { m_heap = heap; m_domain = domain; m_thread = thread; Roots = new List<ClrRoot>(); }
internal override IEnumerable<ClrRoot> EnumerateStackReferences(ClrThread thread, bool includeDead) { if (includeDead) return base.EnumerateStackReferences(thread, includeDead); return EnumerateStackReferencesWorker(thread); }
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()); }
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); } } }
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); }
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); } }
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); }
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)); } } } }
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"]); }
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"); }
/// <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); }); }
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); } } }
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; }
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)}"); } }
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); }
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); }
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); }
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(""); }
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)); } } }
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; }
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; }
public static void WriteCurrentExceptionStackTraceToContext(this ClrThread thread, CommandExecutionContext context, bool displayArgumentsAndLocals) { thread.WriteStackTraceToContext(thread.CurrentException.StackTrace, context, displayArgumentsAndLocals); }
private bool IsUserSuspended(ClrThread thread) { _logger?.LogTrace("Thread user suspended {0}", thread.IsUserSuspended); return(thread.IsUserSuspended); }
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); }
public static ClrStackFrame GetFrame(this ClrThread thread, string functionName) { return(thread.EnumerateStackTrace().Single(sf => sf.Method != null ? sf.Method.Name == functionName : false)); }
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)); }
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; }
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); }
private static ThreadInfo ThreadInfoFromThread(ClrThread thread) { return new ThreadInfo { OSThreadId = thread.OSThreadId, ManagedThreadId = thread.ManagedThreadId }; }
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()); }
public static bool IsThreadPoolThread(this ClrThread thread) { return(thread.IsThreadpoolCompletionPort || thread.IsThreadpoolGate || thread.IsThreadpoolTimer || thread.IsThreadpoolWait || thread.IsThreadpoolWorker); }
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; }
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; }
public static string[] GetStackTraceRepr(this ClrThread thread) => thread.StackTrace .Select(frame => frame.DisplayString.EscapeNull()) .ToArray();