StackTrace / StackFrame不会在生产环境中返回预期的信息 [英] StackTrace/StackFrame don't return expected info in a production environment

查看:151
本文介绍了StackTrace / StackFrame不会在生产环境中返回预期的信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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 System.Diagnostics.StackTrace(ex,true));
}

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



我需要做任何特别的事情使它在IIS上工作?

解决方案


它给我全线/列/方法名称信息,如果我在Visual Studio 2010开发环境中运行它,但是在IIS的生产环境中,它返回所有0,方法名称作为空字符串。


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


我需要做任何特殊的操作才能使其在IIS上工作还有?


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



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



有些问题你没有问:



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



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



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


在调试环境中,StackTrace对象提供了一个保证,堆栈跟踪告诉我当前调用来自哪里


不。堆栈跟踪不会告诉你你从哪里来的地方。堆栈跟踪告诉你你将要下一步。这是有用的,因为你来的地方和你下一步往往有很强的相关性;通常你会回到你所来的地方。



这并不总是真的。有时候,CLR有时可以找出下一步,而不知道你来自哪里,在这种情况下,堆栈跟踪不包含你需要的信息。



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



堆栈跟踪是不可靠的,所以不要依赖它们。使用它们作为诊断帮助。


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


因为攻击者会尝试通过在其上投掷异常输入来使您的服务器失败。如果这使服务器下降,那么攻击者会很高兴。如果它使服务器保持不起,但是将攻击者的源代码泄漏信息更好。现在,他们有更多的信息用于安装更复杂的攻击。<​​/ p>

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


I use the following method in my ASP.NET web application to receive the stack trace for an 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));
}

It gives me full line/column/method name information if I run it in the Visual Studio 2010 dev environment, but in a production environment on the IIS it returns all 0's and the method name as empty string.

Do I need to do anything special to make it work on IIS as well?

解决方案

It gives me full line/column/method name information if I run it in the Visual Studio 2010 dev environment, but in a production environment on the IIS it returns all 0's and the method name as empty string.

Correct. Read the name of the type carefully; that Diagnostics is important. The types in that namespace were designed for diagnosing problems in a debug environment.

Do I need to do anything special to make it work on IIS as well?

No; you need to not use diagnostic tools in production.

If for some reason you want to use diagnostic tools in a production environment, at a minimum you'll need to push the PDB files to the production environment. This might be a dangerous and foolish thing to do, as we'll see below. I recommend that you do not do so.

Some questions you did not ask:

What tool should I be using to get caller information in a production environment?

If you need to get the line number, etc, of a method call, the tool you probably should be using is the new CallerLineNumber and related attributes in C# 5.0. Here's a good blog on them:

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

If you need to get information about the stack trace of an exception, what you see is what you get.

In a debug environment does the StackTrace object provide a guarantee that the stack trace tells me where the current call came from?

No. A stack trace does not tell you where you came from in the first place. A stack trace tells you where you are going next. This is useful because there is often a strong correlation between where you came from and where you're going next; usually you're going back to where you came from.

This is not always true though. The CLR can sometimes figure out where to go next without knowing where you came from, in which case the stack trace doesn't contain the information you need.

For example, tail call optimizations can remove frames from the stack. Inlining optimizations can make a call to a method look like part of the calling method. Asynchronous workflows in C# 5 completely divorce "where you came from" and "where you're going next"; the stack trace of an asynchronous method resumed after an await tells you where you are going after the next await, not how you got into the method before the first await.

Stack traces are unreliable, so do not rely on them. Use them only as a diagnostic aid.

Why is it particularly dangerous to expose diagnostic information in ASP?

Because attackers will attempt to cause your server to fail by throwing "exceptional" inputs at it. If that brings the server down, great, the attackers will be happy. If it keeps the server up but leaks information about your source code to the attacker, even better. Now they have more information to use to mount a more sophisticated attack.

ASP servers should profer up as little diagnostic information as possible in a production environment. The less debug information you have in that production environment, the less likely you are to make a mistake and expose your implementation details to an attacker.

这篇关于StackTrace / StackFrame不会在生产环境中返回预期的信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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