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

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

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上运行?

如果我在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

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

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

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

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

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

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

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

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

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