堆栈跟踪上的错误行号
- 作者: -_-宅_
- 来源: 51数据库
- 2023-02-08
问题描述
我有这个代码
try
{
//AN EXCEPTION IS GENERATED HERE!!!
}
catch
{
SqlService.RollbackTransaction();
throw;
}
上面的代码在这段代码中被调用
Code above is called in this code
try
{
//HERE IS CALLED THE METHOD THAT CONTAINS THE CODE ABOVE
}
catch (Exception ex)
{
HandleException(ex);
}
作为参数传递给方法HandleException"的异常包含堆栈跟踪中throw"行的行号,而不是生成异常的实际行.有谁知道为什么会发生这种情况?
The exception passed as parameter to the method "HandleException" contains the line number of the "throw" line in the stack trace instead of the real line where the exception was generated. Anyone knows why this could be happening?
EDIT1好的,谢谢大家的回答.我把内扣换成了
EDIT1 Ok, thanks to all for your answers. I changed the inner catch for
catch(Exception ex)
{
SqlService.RollbackTransaction();
throw new Exception("Enrollment error", ex);
}
现在我在堆栈跟踪中有正确的行,但我必须创建一个新异常.我希望找到更好的解决方案:-(
Now I have the correct line on the stack trace, but I had to create a new exception. I was hoping to find a better solution :-(
EDIT2也许(如果你有 5 分钟的时间)你可以尝试这个场景来检查你是否得到相同的结果,重新创建不是很复杂.
EDIT2 Maybe (if you have 5 minutes) you could try this scenario in order to check if you get the same result, not very complicated to recreate.
推荐答案
是的,这是异常处理逻辑的限制.如果一个方法包含多个抛出异常的 throw 语句,那么您将获得最后一个抛出异常的行号.此示例代码重现了此行为:
Yes, this is a limitation in the exception handling logic. If a method contains more than one throw statement that throws an exception then you'll get the line number of the last one that threw. This example code reproduces this behavior:
using System;
class Program {
static void Main(string[] args) {
try {
Test();
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
static void Test() {
try {
throw new Exception(); // Line 15
}
catch {
throw; // Line 18
}
}
}
输出:
System.Exception: Exception of type 'System.Exception' was thrown. at Program.Test() in ConsoleApplication1Program.cs:line 18 at Program.Main(String[] args) in ConsoleApplication1Program.cs:line 6
解决方法很简单,只需使用辅助方法来运行可能引发异常的代码.
The work-around is simple, just use a helper method to run the code that might throw an exception.
像这样:
static void Test() {
try {
Test2(); // Line 15
}
catch {
throw; // Line 18
}
}
static void Test2() {
throw new Exception(); // Line 22
}
这种尴尬行为的根本原因是 .NET 异常处理建立在操作系统对异常的支持之上.称为 SEH,Windows 中的结构化异常处理.这是基于堆栈帧的,每个堆栈帧只能有一个活动异常..NET 方法有一个堆栈帧,与方法内的范围块数量无关.通过使用辅助方法,您可以自动获得另一个可以跟踪其自身异常的堆栈帧.当方法包含 throw 语句时,抖动还会自动抑制内联优化,因此无需显式使用 [MethodImpl] 属性.
The underlying reason for this awkward behavior is that .NET exception handling is built on top of the operating system support for exceptions. Called SEH, Structured Exception Handling in Windows. Which is stack-frame based, there can only be one active exception per stack frame. A .NET method has one stack frame, regardless of the number of scope blocks inside the method. By using the helper method, you automatically get another stack frame that can track its own exception. The jitter also automatically suppresses the inlining optimization when a method contains a throw statement so there is no need to explicitly use the [MethodImpl] attribute.
- C#通过fleck实现wss协议的WebSocket多人Web实时聊天(附源码)
- 团队城市未满足要求:MSBuildTools12.0_x86_Path 存在
- 使用 MSBuild.exe 在发布模式下构建 C# 解决方案
- 当我发布 Web 应用程序时,AfterPublish 脚本不运行
- 构建时 T4 转换的产品仅在下一个构建中使用
- ASP.NET Core Application (.NET Framework) for Windows x64 only error in project.assets.json
- 新的 .csproj 格式 - 如何将整个目录指定为“链接文件"到子目录?
- 如何将条件编译符号(DefineConstants)传递给 msbuild
- MSBuild 支持 Visual Studio 2017 RTM 中的 T4 模板
- NuGet 包还原找不到包,没有源
