7

我在我的 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 上也能正常工作?

4

1 回答 1

36

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

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

我是否需要做一些特别的事情才能让它在 IIS 上也能正常工作?

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

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

一些你没有问的问题:

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

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

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

如果您需要获取有关异常堆栈跟踪的信息,所见即所得。

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

不,堆栈跟踪并不会告诉您首先来自哪里。堆栈跟踪会告诉您下一步要去哪里。这很有用,因为您来自哪里和下一步要去哪里之间通常存在很强的相关性。通常你会回到你原来的地方。

但这并不总是正确的。CLR 有时可以在不知道您来自哪里的情况下确定下一步要去哪里,在这种情况下,堆栈跟踪不包含您需要的信息。

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

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

为什么在 ASP 中暴露诊断信息特别危险?

因为攻击者会尝试通过向其抛出“异常”输入来导致您的服务器失败。如果这导致服务器宕机,很好,攻击者会很高兴。如果它使服务器保持正常运行但将有关您的源代码的信息泄露给攻击者,那就更好了。现在他们有更多信息可用于发起更复杂的攻击。

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

于 2013-03-12T17:51:57.720 回答