异常调用堆栈截断,没有任何重新投掷 [英] exception call stack truncated without any re-throwing

查看:186
本文介绍了异常调用堆栈截断,没有任何重新投掷的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个不寻常的情况下,我有一个非常简单的异常越来越抛出陷入了同样的方法。 它不是重新抛出(通常这类问题幼稚程序员)。然而其的StackFrame仅包含一个当前方法。这里是什么样子:

I have an unusual case where I have a very simple Exception getting thrown and caught in the same method. It isn’t re-thrown (the usual kind of problem naïve programmers have). And yet its StackFrame contains only one the current method. Here’s what it looks like:

   at (my class).MyMethod() in C:\(my file path and line)

在现实中有可能是30的方法导致这一在VS2010调试器的调用堆栈,跨六七个不同的组件去。这似乎是不可能为所有已被优化掉。此外,该code是内置的调试模式下,没有优化,对于.NET 4我甚至都(基于<一href="http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx">http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx) .ini文件(其中一个名为[程序] .vshost.ini)中包含相同的文件夹:

In reality there are probably 30 methods leading up to this in the VS2010 debugger's call stack, going across half a dozen different assemblies. It seems impossible for all that to have been optimized out. Moreover, this code is built in debug mode, without optimizations, for .NET 4. I even have (based on http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx) .ini files (including one named [app].vshost.ini) in the same folder containing:

[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0

此外,该方法调用不是在方法结束时,使尾递归优化似乎不大可能进一步

Also, the method calls are not at the end of methods, so tail-recursion optimization seems further unlikely.

至于它是怎么叫:有反射调用堆栈上没有用途,没有任何形式的调用()或BeginInvoke的()。这是一个按钮,点击呼叫的只是一个长链。单击处理是下降的调用栈约10个电话。其下方你可以使用通常的WndProc,NativeWindow.Callback,本机/托管过渡和消息循环。这是最终是从一个C#的EXE组件运行的ShowDialog()调用中。

As to how it is called: there are no uses of reflection on the call stack, no Invoke() or BeginInvoke() of any kind. This is just a long chain of calls from a button click. The click handler is about 10 calls down the call stack. Beneath that you have the usual WndProc, NativeWindow.Callback, native/managed transitions, and message loop. This is ultimately inside a ShowDialog() call which is run from a C# EXE assembly.

现在,我发现我可以构建在我的catch处理堆栈跟踪类的实例,如果我传递异常对象,调用堆栈也短。相反,如果我只需要调用新的堆栈跟踪()不带参数,它产生一个完整的调用堆栈。

Now, I found that I can construct instances of the StackTrace class in my catch handler, and if I pass the Exception object, the call stack is also short. If instead I just call new StackTrace() with no arguments, it yields a complete call stack.

我用反射,企图调试到的Exception类得到抛出其调用栈构建的内部,但我不能设置异常或堆栈跟踪断点。我可以将它们设置在Environment.GetStackTrace()这个方法(这异常调用)不出现施工和投掷过程中被调用,但我不知道是否调试器确实正常工作。 (此方法也得到尽管触发一些其他的事情,所以我不知道该怎么利用它。)

I’ve used Reflector in an attempt to debug into the internals of the Exception class getting thrown and its call stack constructed, but I couldn’t set breakpoints in Exception or in StackTrace. I could set them in Environment.GetStackTrace() and this method (which Exception calls) does not appear to get called during the construction and throwing process, but I don’t know if the debugger is really working properly. (This method does get triggered for some other things though, so I'm not sure what to make of it.)

下面就是该方法的一个片段:

Here’s an excerpt of the method:

private void MyMethod()
{
    ...               
    try
    {
        throw new ApplicationException("Test failure");
    }
    catch (Exception e)
    {
        StackTrace stackTrace1 = new StackTrace(e);
        StackTrace stackTrace2 = new StackTrace(e, false);
        StackTrace stackTrace3 = new StackTrace(e, true);
        StackTrace stackTrace4 = new StackTrace();
        string STs = stackTrace1.ToString() + "\n---\n"
            + stackTrace2.ToString() + "\n---\n"
            + stackTrace3.ToString() + "\n---\n"
            + stackTrace4.ToString();
        Log(EventSeverity.Debug, STs);
        ...
        }
    }

这真是pretty的简单:抛出异常,捕捉和记录它

It’s really pretty simple: Throw exception, catch and log it.

我得到独立运行,单行调用堆栈时,无论是在调试器或相同的结果。我知道我已经在我们的code碱基看到这个问题在其他地方。 previously我曾以为这是由于重新抛出异常,但在很多情况下是我们登录权的初始catch块中。我很困惑,所有的网络搜索我所做的还没有生产任何东西。

I get the same results either in the debugger or when running standalone—a one-line call stack. And I know I have seen this problem elsewhere in our code base. Previously I had assumed it was due to re-throwing exceptions, but in a lot of cases it we log right inside the initial catch block. I’m quite baffled and all the web searching I’ve done hasn’t produce anything.

这是一个有点太多添加为一个注释的答案提供的,但这里的一些详细信息:

This is a little too much to add as a comment to the answer provided, but here's some more information:

我现在看到的这种行为是在讨论 <一href="http://dotnetthoughts.word$p$pss.com/2007/10/27/where-did-my-exception-occur/">http://dotnetthoughts.word$p$pss.com/2007/10/27/where-did-my-exception-occur/并且这是在<一个实际上描述href="http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx">http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx (虽然我认为人们可以轻易错过他们在说什么有)。

I now see that this behavior is discussed at http://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/ and that it is actually described at http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx (though I think one could easily miss what they're saying there).

所以,我想我的解决方案将是一个有点冒险的思念。我们有一个核心方法,我们通常所说的格式化异常。在那个方法,我将创建一个新的堆栈跟踪()有和没有异常的对象。然后我会寻找那些处于异常的堆栈跟踪底部的方法,并在新的堆栈跟踪()显示下一切,表明它被称为由一系列调用。

So I guess my "solution" will be a little hit-or-miss. We have a central method we usually call to format exceptions. Inside that method, I'll create a new StackTrace() both with and without the Exception object. Then I'll look for the method that is at the bottom of the Exception's stack trace, and display everything beneath that in the new StackTrace(), indicating it was called by that series of calls.

当然,不利的一面是,如果不使用这种方法,信息不会在那里。但是,我不得不想到某种$ C $的C更改的地方。

The down side of course is that if this method isn't used, the information won't be there. But I had to expect some kind of code change somewhere.

推荐答案

当一个异常被抛出,只是局部堆栈跟踪将在 Exception.StackTrace 属性来使用。堆栈只显示通话,直到被捕获异常的方法。要获得完整的堆栈(如你已经注意到),你应该创建一个新的堆栈跟踪()对象。

When an exception is thrown, only a partial stack trace will be used in the Exception.StackTrace property. The stack only shows calls up until the method that is catching the exception. To get the full stack (as you have noted) you should create a new StackTrace() object.

我找不到此刻它的任何联系,但我相信,堆栈跟踪被走了栈,同时抛出异常建成。一旦异常到达catch块,堆栈停止正在编制。因此,你只能得到一个局部堆栈。

I can't find any links on it at the moment but I believe the stack trace is built by walking up the stack while throwing the exception. Once the exception reaches a catch block, the stack stops being compiled. Therefore, you only get a partial stack.

通常情况下,一个catch块关心的不是谁把它称为,但那里的异常源自

Typically, a catch block is not concerned with who called it, but where the exception is originating from.

这篇关于异常调用堆栈截断,没有任何重新投掷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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