StackTrace / StackFrame不会在生产环境中返回预期信息

时间:2013-03-12 17:42:42

标签: c# asp.net debugging stack-trace visual-studio-debugging

我在ASP.NET Web应用程序中使用以下方法来接收异常的堆栈跟踪:

public static void getStackTraceInfo(System.Diagnostics.StackTrace trace)
{
    for (int i = 0; i < trace.FrameCount; i++)
    {
        int nLine = trace.GetFrame(i).GetFileLineNumber();
        int nCol = trace.GetFrame(i).GetFileColumnNumber();
        string methodName = trace.GetFrame(i).GetMethod().Name;
    }
}

try
{
}
catch(Exception ex)
{
    getStackTraceInfo(new System.Diagnostics.StackTrace(ex, true));
}

如果我在Visual Studio 2010开发环境中运行它,它会为我提供完整的行/列/方法名称信息,但在IIS上的生产环境中,它会将所有0和方法名称返回为空字符串。

我是否还需要做一些特别的工作才能使它在IIS上运行?

1 个答案:

答案 0 :(得分:32)

  

如果我在Visual Studio 2010开发环境中运行它,它会为我提供完整的行/列/方法名称信息,但在IIS上的生产环境中,它会将所有0和方法名称返回为空字符串。

正确。仔细阅读该类型的名称; Diagnostics很重要。该命名空间中的类型用于诊断调试环境中的问题。

  

我是否还需要做一些特别的工作才能使它在IIS上运行?

没有;您不需要在生产中使用诊断工具。

如果由于某种原因您想在生产环境中使用诊断工具,则至少需要将PDB文件推送到生产环境。这可能是一件危险且愚蠢的事情,我们将在下面看到。我建议你不这样做。

你没有问过一些问题:

  

我应该使用什么工具在生产环境中获取来电者信息?

如果需要获取方法调用的行号等,您可能应该使用的工具是C#5.0中新的CallerLineNumber和相关属性。这是关于他们的好博客:

http://blog.slaks.net/2011/10/subtleties-of-c-5s-new-callerlinenumber.html

如果您需要获取有关异常的堆栈跟踪的信息,您所看到的就是您所获得的。

  

在调试环境中,StackTrace对象是否保证堆栈跟踪告诉我当前调用来自哪里

没有。堆栈跟踪不会告诉您首先来自哪里。堆栈跟踪告诉您下一步的位置。这很有用,因为你来自哪里和下一步之间往往有很强的相关性;通常你会回到你来自的地方。

但事实并非如此。 CLR有时可以在不知道您来自何处的情况下找出下一步的位置,在这种情况下,堆栈跟踪不包含您需要的信息。

例如,尾调用优化可以从堆栈中删除帧。内联优化可以使对方法的调用看起来像调用方法的一部分。 C#5中的异步工作流完全离婚“你来自哪里”和“你下一步去哪里”;在await告诉您下一个await之后的去向,而不是在第一个await之前进入方法之后,异步方法的堆栈跟踪是否已恢复。

堆栈跟踪不可靠,因此不要依赖它们。仅将它们用作诊断辅助工具。

  

为什么在ASP中公开诊断信息特别危险?

因为攻击者会通过向其投掷“特殊”输入来尝试使服务器失败。如果这会让服务器失灵,那么攻击者会很高兴。如果它使服务器保持运行但将有关源代码的信息泄露给攻击者,那就更好了。现在,他们有更多信息可用于发动更复杂的攻击。<​​/ p>

ASP服务器应该在生产环境中尽可能少地获取诊断信息。您在该生产环境中的调试信息越少,您犯错的可能性就越小,并将您的实施细节暴露给攻击者。