C# } } 与@MarcosMeli的回答一样,这是不正确的。正如@Hans Loken所说,GetCurrentProcess()方法返回一个ProcessThreadCollection,其中包含ProcessThread对象,而不是Thread对象。据我

C# } } 与@MarcosMeli的回答一样,这是不正确的。正如@Hans Loken所说,GetCurrentProcess()方法返回一个ProcessThreadCollection,其中包含ProcessThread对象,而不是Thread对象。据我,c#,.net,multithreading,C#,.net,Multithreading,} } 与@MarcosMeli的回答一样,这是不正确的。正如@Hans Loken所说,GetCurrentProcess()方法返回一个ProcessThreadCollection,其中包含ProcessThread对象,而不是Thread对象。据我所知,您无法从ProcessThread获取堆栈跟踪,因为它代表Windows本机线程。刚刚从客户端位置返回了一些调试转储,这对我们很有用。很酷。代码很棒,谢谢!我可以建议添加方法签名,就像使用f.method.GetFullSignature

} }
与@MarcosMeli的回答一样,这是不正确的。正如@Hans Loken所说,GetCurrentProcess()方法返回一个ProcessThreadCollection,其中包含ProcessThread对象,而不是Thread对象。据我所知,您无法从ProcessThread获取堆栈跟踪,因为它代表Windows本机线程。刚刚从客户端位置返回了一些调试转储,这对我们很有用。很酷。代码很棒,谢谢!我可以建议添加方法签名,就像使用f.method.GetFullSignature()一样。在重写的情况下可能会有所帮助,因为ClrMD目前不支持.NET 4.6。这篇文章有一个解决方案:
在Microsoft.Diagnostics.Runtime.dll中发生了一个类型为“System.NullReferenceException”的未经处理的异常,该异常位于
结果中。添加
注意:此库在读取堆栈跟踪时导致内存泄漏:。您可能不想在生产中使用它。
var trace = new System.Diagnostics.StackTrace(exception);
var result = new Dictionary<int, string[]>();

var pid = Process.GetCurrentProcess().Id;

using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive))
{
    ClrInfo runtimeInfo = dataTarget.ClrVersions[0];
    var runtime = runtimeInfo.CreateRuntime();

    foreach (var t in runtime.Threads)
    {
        result.Add(
            t.ManagedThreadId,
            t.StackTrace.Select(f =>
            {
                if (f.Method != null)
                {
                    return f.Method.Type.Name + "." + f.Method.Name;
                }

                return null;
            }).ToArray()
        );
    }
}

var json = JsonConvert.SerializeObject(result);

zip.AddEntry("_threads.json", json);
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.Diagnostics.Runtime;

namespace CSharpUtils.wrc.utils.debugging
{
    public static class StackTraceAnalysis
    {
        public static string GetAllStackTraces()
        {
            var result = new StringBuilder();
            
            using (var target = DataTarget.CreateSnapshotAndAttach(Process.GetCurrentProcess().Id))
            {
                var runtime = target.ClrVersions.First().CreateRuntime();

                // We can't get the thread name from the ClrThead objects, so we'll look for
                // Thread instances on the heap and get the names from those.    
                var threadNameLookup = new Dictionary<int, string>();
                foreach (var obj in runtime.Heap.EnumerateObjects())
                {
                    if (!(obj.Type is null) && obj.Type.Name == "System.Threading.Thread")
                    {
                        var threadId = obj.ReadField<int>("m_ManagedThreadId");
                        var threadName = obj.ReadStringField("m_Name");
                        threadNameLookup[threadId] = threadName;
                    }
                }

                foreach (var thread in runtime.Threads)
                {
                    threadNameLookup.TryGetValue(thread.ManagedThreadId, out string threadName);
                    result.AppendLine(
                        $"ManagedThreadId: {thread.ManagedThreadId}, Name: {threadName}, OSThreadId: {thread.OSThreadId}, Thread: IsAlive: {thread.IsAlive}, IsBackground: {thread.IsBackground}");
                    foreach (var clrStackFrame in thread.EnumerateStackTrace())
                        result.AppendLine($"{clrStackFrame.Method}");
                }
            }

            return result.ToString();
        }
    }
}