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

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

问题描述

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

 公共静态无效getStackTraceInfo(System.Diagnostics.StackTrace跟踪)
{
    的for(int i = 0; I< trace.FrameCount;我++)
    {
        INT n线段= trace.GetFrame(I).GetFileLineNumber();
        INT NCOL = trace.GetFrame(ⅰ).GetFileColumnNumber();
        字符串的方法名= trace.GetFrame(I).GetMethod()名称。
    }
}尝试
{
}
赶上(异常前)
{
    getStackTraceInfo(新System.Diagnostics.StackTrace(恩,真));
}

这给了我充分的行/列/方法的名称信息,如果我在Visual Studio 2010开发环境中运行,但在生产环境上的IIS返回全0和方法名作为空字符串。

我需要做什么特别,使其在IIS上工作呢?


解决方案

  

这给了我充分的行/列/方法的名称信息,如果我在Visual Studio 2010开发环境中运行,但在生产环境上的IIS返回全0和方法名作为空字符串。


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


  

我需要做什么特别,使其在IIS上工作呢?


没有;你需要不使用的诊断的工具中的生产

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

几个问题,你没有问:


  

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


如果你需要得到行号等,方法调用的,你可能应该使用的工具是新的 CallerLineNumber 和相关属性,在C#5.0。这里有他们一个很好的博客:

<一个href=\"http://blog.slaks.net/2011/10/subtleties-of-c-5s-new-callerlinenumber.html\">http://blog.slaks.net/2011/10/subtleties-of-c-5s-new-callerlinenumber.html

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


  

在调试环境确实堆栈跟踪目标提供了保证,该堆栈跟踪告诉我的其中,当前呼叫来自何方的?


没有。堆栈跟踪不告诉你,你来自哪里摆在首位来了。堆栈跟踪告诉你的你要去哪里,下一个的。因为经常有,你来自哪里,你接下来要去的地方之间有很强的相关性,这非常有用;通常你会回到你原来的地方。

这并不总是正确的,但。在CLR有时会揣摩出下次去不知道,你是从哪里来的,在这种情况下,堆栈跟踪不包含您所需要的信息。

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

钻进方法之前

堆栈痕迹是不可靠的,所以不要依靠他们。只能将其用作辅​​助诊断。


  

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


由于攻击者试图使你的服务器通过它扔例外的投入失败。如果带来的服务器关闭,大,攻击者会很高兴。如果保持服务器最多不过的泄露了你的源$ C ​​$ C到攻击者的信息的,甚至更好。现在,他们不得不使用挂载一个更复杂的攻击的详细信息。

的ASP服务器应profer向上在生产环境中尽可能少的诊断信息成为可能。您在生产环境中具有较少的调试信息,就越有可能你是犯了一个错误,并暴露你的实现细节给攻击者。

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.

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

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