堆栈跟踪中的行号错误 [英] Wrong line number on stack trace

查看:231
本文介绍了堆栈跟踪中的行号错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个代码

try
{
  //AN EXCEPTION IS GENERATED HERE!!!
}
catch  
{
   SqlService.RollbackTransaction();
   throw;
}

此代码中调用以上代码

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
好​​的,谢谢你的回答。我更改了内部的catch

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 ConsoleApplication1\Program.cs:line 18
   at Program.Main(String[] args) in ConsoleApplication1\Program.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异常处理是建立在操作系统支持的例外之上的。在Windows中称为SEH,结构化异常处理。哪个是基于堆栈帧的,每个堆栈帧只能有一个活动异常。 .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.

这篇关于堆栈跟踪中的行号错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆