C# 确定从转储文件引发异常的线程
假设我的应用程序有两个线程A和B,每个线程抛出一个异常。我可以通过使用C# 确定从转储文件引发异常的线程,c#,multithreading,exception,windbg,sos,C#,Multithreading,Exception,Windbg,Sos,假设我的应用程序有两个线程A和B,每个线程抛出一个异常。我可以通过使用~{threadid}s然后运行来确定哪个线程引发了哪个异常吗!pe?通常只有一个线程抛出导致应用程序终止的异常。也就是说,我看到它发生在一个调试会话中,其中除异常外的线程被冻结,其他线程被恢复 NET!threads命令将列出.NET线程和每个线程上的异常: 0:000> !threads ThreadCount: 6 UnstartedThread: 0 BackgroundThread: 2 PendingThre
~{threadid}s
然后运行来确定哪个线程引发了哪个异常吗!pe
?通常只有一个线程抛出导致应用程序终止的异常。也就是说,我看到它发生在一个调试会话中,其中除异常外的线程被冻结,其他线程被恢复
NET!threads
命令将列出.NET线程和每个线程上的异常:
0:000> !threads
ThreadCount: 6
UnstartedThread: 0
BackgroundThread: 2
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
PreEmptive Lock
ID OSID ThreadOBJ State GC GC Alloc Context Domain Count APT Exception
0 1 251c 00000000003deff0 201a220 Enabled 00000000027846f8:0000000002785fd0 0000000000382ca0 0 MTA
2 2 2b10 0000000000a88280 b220 Enabled 0000000000000000:0000000000000000 0000000000382ca0 0 MTA (Finalizer)
3 3 255c 0000000000aacac0 b020 Enabled 00000000027862b8:0000000002787fd0 0000000000382ca0 0 MTA System.ArgumentException (0000000002786090)
4 4 2a48 0000000000aad5b0 b020 Enabled 000000000278a290:000000000278bfd0 0000000000382ca0 0 MTA System.NotImplementedException (000000000278a070)
5 5 2e50 0000000000aa20d0 b020 Enabled 0000000002788268:0000000002789fd0 0000000000382ca0 0 MTA System.OutOfMemoryException (0000000002788048)
6 6 d50 0000000000aa2e00 b020 Enabled 000000000278c280:000000000278dfd0 0000000000382ca0 0 MTA System.Threading.ThreadInterruptedException (000000000278c060)
然后,您可以切换到列为ID
的线程,并转储该线程上的异常(~xs;!pe
或~xe!pe
,其中x是ID):
在非托管代码中,当使用~
显示线程时,抛出异常的线程将标记为#
:
0:000> ~
. 0 Id: 2b14.251c Suspend: 1 Teb: 000007ff`fffde000 Unfrozen
1 Id: 2b14.71c Suspend: 1 Teb: 000007ff`fffdb000 Unfrozen
2 Id: 2b14.2b10 Suspend: 1 Teb: 000007ff`fffd9000 Unfrozen
# 3 Id: 2b14.255c Suspend: 1 Teb: 000007ff`fffd7000 Unfrozen
4 Id: 2b14.2a48 Suspend: 1 Teb: 000007ff`fffd5000 Unfrozen
5 Id: 2b14.2e50 Suspend: 1 Teb: 000007ff`fffd3000 Unfrozen
6 Id: 2b14.d50 Suspend: 1 Teb: 000007ff`fff0e000 Unfrozen
如果看不到
#
,则它通常隐藏在后面。您可以使用~\s
切换到此线程。请注意,WinDbg只显示一个#
,尽管其他线程上也有例外。我不知道如何在本机端解决这个问题。通常只有一个线程抛出导致应用程序终止的异常。也就是说,我看到它发生在一个调试会话中,其中除异常外的线程被冻结,其他线程被恢复
NET!threads
命令将列出.NET线程和每个线程上的异常:
0:000> !threads
ThreadCount: 6
UnstartedThread: 0
BackgroundThread: 2
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
PreEmptive Lock
ID OSID ThreadOBJ State GC GC Alloc Context Domain Count APT Exception
0 1 251c 00000000003deff0 201a220 Enabled 00000000027846f8:0000000002785fd0 0000000000382ca0 0 MTA
2 2 2b10 0000000000a88280 b220 Enabled 0000000000000000:0000000000000000 0000000000382ca0 0 MTA (Finalizer)
3 3 255c 0000000000aacac0 b020 Enabled 00000000027862b8:0000000002787fd0 0000000000382ca0 0 MTA System.ArgumentException (0000000002786090)
4 4 2a48 0000000000aad5b0 b020 Enabled 000000000278a290:000000000278bfd0 0000000000382ca0 0 MTA System.NotImplementedException (000000000278a070)
5 5 2e50 0000000000aa20d0 b020 Enabled 0000000002788268:0000000002789fd0 0000000000382ca0 0 MTA System.OutOfMemoryException (0000000002788048)
6 6 d50 0000000000aa2e00 b020 Enabled 000000000278c280:000000000278dfd0 0000000000382ca0 0 MTA System.Threading.ThreadInterruptedException (000000000278c060)
然后,您可以切换到列为ID
的线程,并转储该线程上的异常(~xs;!pe
或~xe!pe
,其中x是ID):
在非托管代码中,当使用~
显示线程时,抛出异常的线程将标记为#
:
0:000> ~
. 0 Id: 2b14.251c Suspend: 1 Teb: 000007ff`fffde000 Unfrozen
1 Id: 2b14.71c Suspend: 1 Teb: 000007ff`fffdb000 Unfrozen
2 Id: 2b14.2b10 Suspend: 1 Teb: 000007ff`fffd9000 Unfrozen
# 3 Id: 2b14.255c Suspend: 1 Teb: 000007ff`fffd7000 Unfrozen
4 Id: 2b14.2a48 Suspend: 1 Teb: 000007ff`fffd5000 Unfrozen
5 Id: 2b14.2e50 Suspend: 1 Teb: 000007ff`fffd3000 Unfrozen
6 Id: 2b14.d50 Suspend: 1 Teb: 000007ff`fff0e000 Unfrozen
如果看不到#
,则它通常隐藏在后面。您可以使用~\s
切换到此线程。请注意,WinDbg只显示一个#
,尽管其他线程上也有例外。我不知道如何在本机端找到它。您的线程是否命名,您是否询问是否可以获得名称?或者您只是在寻找人工/非人工线程ID?只有一个线程的未处理异常将触发记录小型转储的代码。如果不太可能的情况是,有另一个线程同时抛出,那么您的小转储应该会在CLR中看到它繁忙,或者在同步对象上阻塞,以确保小转储可以被安全地记录。@ScottChamberlain线程未命名。如果我能得到每个线程的堆栈跟踪和它抛出的异常,那就好了enough@HansPassant收集转储文件是为了提高cpu使用率。它也包含一些例外。你的线程有名字吗?你是在问你能不能得到名字?或者您只是在寻找人工/非人工线程ID?只有一个线程的未处理异常将触发记录小型转储的代码。如果不太可能的情况是,有另一个线程同时抛出,那么您的小转储应该会在CLR中看到它繁忙,或者在同步对象上阻塞,以确保小转储可以被安全地记录。@ScottChamberlain线程未命名。如果我能得到每个线程的堆栈跟踪和它抛出的异常,那就好了enough@HansPassant收集转储文件是为了提高cpu使用率。它还包含一些例外情况。