bh2*_*213 31 .net debugging multithreading stack-trace visual-studio-debugging
可以使用System.Diagnostics.StackTrace获取堆栈跟踪,但必须暂停线程.暂停和恢复功能已经过时,所以我希望存在更好的方法.
Joe*_*ari 21
到目前为止,这对我有用:
StackTrace GetStackTrace (Thread targetThread)
{
StackTrace stackTrace = null;
var ready = new ManualResetEventSlim();
new Thread (() =>
{
// Backstop to release thread in case of deadlock:
ready.Set();
Thread.Sleep (200);
try { targetThread.Resume(); } catch { }
}).Start();
ready.Wait();
targetThread.Suspend();
try { stackTrace = new StackTrace (targetThread, true); }
catch { /* Deadlock */ }
finally
{
try { targetThread.Resume(); }
catch { stackTrace = null; /* Deadlock */ }
}
return stackTrace;
}
Run Code Online (Sandbox Code Playgroud)
如果它死锁,则自动释放死锁并返回空跟踪.(然后你可以再次调用它.)
我应该补充说,经过几天的测试,我只能在我的Core i7机器上创建死锁.但是,当CPU以100%运行时,死锁在单核VM上很常见.
Dir*_*nné 17
这是一个旧的线程,但只是想提出有关提议的解决方案的警告:暂停和恢复解决方案不起作用 - 我只是在我的代码中遇到了死锁,尝试序列Suspend/StackTrace/Resume.
问题是StackTrace构造函数执行RuntimeMethodHandle - > MethodBase转换,这会更改内部MethodInfoCache,它会锁定.发生了死锁,因为我正在检查的线程也正在进行反射,并持有该锁定.
遗憾的是,暂停/恢复内容不是在StackTrace构造函数内部完成的 - 然而这个问题很容易被绕过.
And*_*eas 12
正如我在评论中提到的那样,所提出的解决方案仍然存在很小的死锁概率.请在下面找到我的版本.
private static StackTrace GetStackTrace(Thread targetThread) {
using (ManualResetEvent fallbackThreadReady = new ManualResetEvent(false), exitedSafely = new ManualResetEvent(false)) {
Thread fallbackThread = new Thread(delegate() {
fallbackThreadReady.Set();
while (!exitedSafely.WaitOne(200)) {
try {
targetThread.Resume();
} catch (Exception) {/*Whatever happens, do never stop to resume the target-thread regularly until the main-thread has exited safely.*/}
}
});
fallbackThread.Name = "GetStackFallbackThread";
try {
fallbackThread.Start();
fallbackThreadReady.WaitOne();
//From here, you have about 200ms to get the stack-trace.
targetThread.Suspend();
StackTrace trace = null;
try {
trace = new StackTrace(targetThread, true);
} catch (ThreadStateException) {
//failed to get stack trace, since the fallback-thread resumed the thread
//possible reasons:
//1.) This thread was just too slow (not very likely)
//2.) The deadlock ocurred and the fallbackThread rescued the situation.
//In both cases just return null.
}
try {
targetThread.Resume();
} catch (ThreadStateException) {/*Thread is running again already*/}
return trace;
} finally {
//Just signal the backup-thread to stop.
exitedSafely.Set();
//Join the thread to avoid disposing "exited safely" too early. And also make sure that no leftover threads are cluttering iis by accident.
fallbackThread.Join();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我认为,ManualResetEventSlim"fallbackThreadReady"并不是必需的,但为什么在这种微妙的情况下会冒任何风险呢?
看起来这是过去受支持的操作,但不幸的是,Microsoft 已经过时了:https : //msdn.microsoft.com/en-us/library/t2k35tat(v= vs.110) .aspx
归档时间: |
|
查看次数: |
13562 次 |
最近记录: |