最近,我正在调试我们的应用程序中的“挂起”问题。我对这个工具很陌生,但是对于我在DebugDiag分析中看到了什么有一个特别的问题。我会另行发帖回答其他问题。它有一个题为“以前的.NET异常(所有.NET堆中的异常)”的部分,其中列出了5个异常:
Exception Type Count Message Stack Trace
System.Exception 1 <none> ;
System.OutOfMemoryException 1 <none> ;
System.StackOverflowException 1 <none> ;
System.ExecutionEngineException 1 <none> ;
System.Threading.ThreadAbortException 2 <none> ; 有人能帮我理解几件事吗?
提前感谢!
发布于 2020-06-26 11:41:02
这一节的标题是什么意思?“以前的.NET例外”?
当发生异常时,它可能由使用try{} catch{}构造的代码处理。在许多情况下(至少我在代码中看到的情况),异常正在转换为其他异常。原因通常是某种API,它只会抛出“属于”的异常,即库定义的类型的异常:
try
{
DoSomething();
}
catch (ArgumentException)
{
throw new MyWhateverLibraryException();
}而且,人们通常不设置InnerException属性,尽管这样做并不难:
try
{
DoSomething();
}
catch (ArgumentException argex)
{
var myex = new MyWhateverLibraryException();
myex.InnerException = argex;
throw myex;
}无论如何,如果不正确执行,原始异常就会消失,并且调试这种情况会变得更加困难。
然而,一个异常将不会花很长时间来泡沫向上,并导致崩溃导致崩溃转储。在许多情况下,垃圾收集器将没有足够的时间收集不再引用的异常。
DebugDiag试图使丢失的异常对您可用。它所做的基本上是列出所有在其名称中有异常的对象,假设它们是异常。这相当于SOS命令!dumpheap -type Exception。

在某些情况下,您可能会发现有兴趣的例外,所以这可能是有帮助的。但在很多情况下,它只会列出6种默认的异常,这是更令人困惑而不是有帮助的。
如果有异常抛出,为什么它不会出现在日志中,为什么应用程序不会中止而不是挂起呢?
您看到的6个异常是“默认”异常,它存在于每个.NET项目中,甚至在一个简单的Hello项目中也是如此。这些异常在每个AppDomain中只创建一次,并且始终具有默认的AppDomain。
它们是为特殊的场合而创造的。其中一些问题可以很容易地解释:
new。创建OutOfMemoryException将再次导致OutOfMemoryException。ThreadAbortExceptions可能也有类似的原因。我真不知道普通的例外有什么好处。
为什么没有消息或堆栈跟踪相关联?
那是因为他们还没被扔出去。其中一些在抛出时甚至可能得不到调用堆栈,例如,在发生OutOfMemoryException的情况下,没有用于构建堆栈跟踪的内存。StackOverflowException也是如此。
是否有更好的方法/工具来确定这些来源?
不是的。这只是知识的问题。现在你获得了这样的知识:-)
这笔赏金与
从有信誉的来源寻找答案
我不知道什么才算是有信誉的来源。我可以提供一个存档的苔丝·费兰德斯的博客文章。苔丝·费兰德斯是微软ASP.NET升级工程师。你会发现,在2009年,违约的例外并不像现在那么多。
如果你想要一本书,那么它很可能在Mario的“高级.NET调试”书中。我有这本书,但目前没有,否则我会查一下的。
在.NET CLR源代码中可以找到appdomain.cpp,它有一个名为void SystemDomain::CreatePreallocatedExceptions()的方法。甚至我都不知道有一个正常的ThreadAbortException和一个“粗鲁”的ThreadAbortException。哇!
EXCEPTIONREF pRudeAbortException = (EXCEPTIONREF)AllocateObject(g_pThreadAbortExceptionClass);
...
EXCEPTIONREF pAbortException = (EXCEPTIONREF)AllocateObject(g_pThreadAbortExceptionClass);用于自己测试某些语句的源代码:
using System;
namespace DefaultExceptions
{
class ThisDoesNotDeriveFromException
{ }
class Program
{
static void Main()
{
var noexception = new ThisDoesNotDeriveFromException();
Console.WriteLine("This is just an example to demonstrate the presence of some default exceptions.");
Console.WriteLine("Create a crash dump now, so you can analyze it with WinDbg and SOS or DebugDiag.");
Console.WriteLine("Commands:");
Console.WriteLine(".loadby sos clr");
Console.WriteLine("!dumpheap -type Exception");
Console.ReadLine();
Console.WriteLine(noexception.ToString()); // avoid noexception being GC'd
}
}
}https://stackoverflow.com/questions/62474245
复制相似问题