Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StackTrace/StackFrame don't return expected info in a production environment

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?

like image 551
ahmd0 Avatar asked Mar 12 '13 17:03

ahmd0


1 Answers

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.

like image 101
Eric Lippert Avatar answered Nov 20 '22 15:11

Eric Lippert