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

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

问题描述

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

code以上的被称为这个code

Code above is called in this code

try
{
  //HERE IS CALLED THE METHOD THAT CONTAINS THE CODE ABOVE
}
catch (Exception ex)
{
   HandleException(ex);
}

作为参数传递给方法HandleException传递的异常包含在堆栈跟踪,而不是在那里生成异常的实线的扔行的行号。任何人都知道这可能是为什么发生?

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语句,那么你会得到最后一个抛出的行号。这个例子code重现此行为:

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

的变通方法很简单,只需使用一个辅助方法来运行code,它可能会抛出异常。

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方法有一个栈帧,不论何种方法范围内的块数的。通过使用helper方法,您将自动得到另一个堆栈帧,可以跟踪自己的异常。抖动也会自动燮presses内联优化时的方法中包含的的语句,因此没有必要明确地使用[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天全站免登陆