我发现没有办法在.NET的所有线程上转储堆栈,既不是发送给进程的信号,也不是对所有线程的编程访问。我只能通过Thread.CurrentThread访问当前线程。
有什么窍门吗?
发布于 2009-03-05 16:04:03
为了省去其他人的麻烦,这里是以上代码到c#的端口:
static void WriteThreadInfo(StringBuilder sw, IEnumerable<Thread> threads)
{
foreach(Thread thread in threads)
{
if(!thread.IsAlive) continue;
sw.Append(String.Concat("THREAD NAME: ", thread.Name));
sw.Append(GetStackTrace(thread));
sw.AppendLine();
sw.AppendLine();
}
}
static String GetStackTrace(Thread t)
{
t.Suspend();
var trace1 = new StackTrace(t, true);
t.Resume();
String text1 = System.Environment.NewLine;
var builder1 = new StringBuilder(255);
for (Int32 num1 = 0; (num1 < trace1.FrameCount); num1++)
{
StackFrame frame1 = trace1.GetFrame(num1);
builder1.Append(" at ");
System.Reflection.MethodBase base1 = frame1.GetMethod();
Type type1 = base1.DeclaringType;
if (type1 != null)
{
String text2 = type1.Namespace;
if (text2 != null)
{
builder1.Append(text2);
builder1.Append(".");
}
builder1.Append(type1.Name);
builder1.Append(".");
}
builder1.Append(base1.Name);
builder1.Append("(");
System.Reflection.ParameterInfo [] infoArray1 = base1.GetParameters();
for (Int32 num2 = 0; (num2 < infoArray1.Length); num2++)
{
String text3 = "<UnknownType>";
if (infoArray1[num2].ParameterType != null)
{
text3 = infoArray1[num2].ParameterType.Name;
}
builder1.Append(String.Concat(((num2 != 0) ? ", " : ""), text3, " ", infoArray1[num2].Name));
}
builder1.Append(")");
if (frame1.GetILOffset() != -1)
{
String text4 = null;
try
{
text4 = frame1.GetFileName();
}
catch (System.Security.SecurityException)
{
}
if (text4 != null)
{
builder1.Append(String.Concat(" in ", text4, ":line ", frame1.GetFileLineNumber().ToString()));
}
}
if (num1 != (trace1.FrameCount - 1))
{
builder1.Append(text1);
}
}
return builder1.ToString();
}我还没有找到在C# (只有ProcessThreads)中获取所有托管线程列表的方法,所以看起来您确实需要维护自己感兴趣的线程列表。
我还发现我不能在运行的线程上调用new Stacktrace(t,true),所以我添加了暂停和恢复。显然,您需要考虑这是否会导致问题,如果您线程转储您的生产应用程序。
顺便说一句,我们把这个调用放在我们的应用程序的wcf rest接口上,所以很容易做到。
发布于 2013-08-30 23:29:15
在这一点上,我所见过的为.NET CLR生成线程转储的最佳工具是DebugDiag。此工具将生成活动CLR线程的非常详细的报告(使用崩溃/挂起分析器)以及建议。
我建议查看以下.NET DebugDiag tutorial,因为它显示了生产问题之后的实际分析过程。具体步骤如下:
发布于 2016-07-22 20:24:20
如果您需要以编程方式完成此操作(可能您希望在CI过程中自动转储),您可以使用this answer中的信息来回答不同的问题。
基本上,使用CLR MD附加到您自己的进程
using Microsoft.Diagnostics.Runtime;
using (DataTarget target = DataTarget.AttachToProcess(
Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive))
{
ClrRuntime runtime = target.ClrVersions.First().CreateRuntime();
foreach (ClrThread thread in runtime.Threads)
{
IList<ClrStackFrame> stackFrames = thread.StackTrace;
PrintStackTrace(stackFrames);
}
}这里把PrintStackTrace作为练习留给读者。
https://stackoverflow.com/questions/190236
复制相似问题