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