exception会在try / catch上下文中丢失部分堆栈跟踪

我有两个例子。 在第一种情况下,调试器捕获未处理的exception:

static void Main(string[] args) { Exec(); } static void Exec() { throw new Exception(); } 

并且exception具有完整的堆栈跟踪:

  at ConsoleApplication28.Program.Exec() at ConsoleApplication28.Program.Main(String[] args) at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() 

第二种情况:

 static void Main(string[] args) { Exec(); } static void Exec() { try { throw new Exception(); } catch (Exception ex) { } // Breakpoint } 

在断点处,exception具有短栈跟踪:

  at ConsoleApplication28.Program.Exec() 

为什么在第二种情况下,stacktraces被切割为包含方法,以及如何防止它? 我需要完整的堆栈跟踪来进行bug报告,否则有时候找不到问题是不可能的,没有完整的堆栈跟踪。

您在Visual Studio调试器中看到的是Visual Studio托管进程正在捕获的未处理exception(即前两个堆栈帧之后的所有内容都是该VS“主机管道”的一部分)。 如果您禁用托管过程(项目属性 – >启用Visual Studio托管过程),您将在两种情况下都看到“短”堆栈跟踪(尽管在第二种情况下您将看不到Main的堆栈框架,因为exception是“处理”,不允许传播到Main )。 这个较短的堆栈跟踪是您在调试器外部运行应用程序时将看到的堆栈跟踪。

堆栈的工作方式与您想象的一样 – 每个方法调用将另一个堆栈帧推送到其上,并且在方法结束时,其堆栈帧被“弹出”,或从堆栈中移除。 您在exception上看到的堆栈跟踪由抛出exception的帧中的堆栈帧组成,返回到最终处理exception的帧,因为堆栈是“展开的”。