BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

.NET Framework
.NET 2.0+

Obtaining a Stack Trace

Call stacks are used to control the flow of programs as methods and properties are executed and terminated. When adding diagnostic code, such as logging, to software it can be useful to examine the call stack for a thread or exception using a stack trace.

Capturing Source Information

If you are reading the call stack to obtain diagnostic information, you can use several other methods to return extra information about the relationship between a stack frame and the source code it represents. The GetFileName method gets a string containing the name of the source code file that holds the member. For more detail, you can get the line number and column number of the command in the source code using the GetFileLineNumber and GetFileColumnNumber methods.

To retrieve the extra source code information there are two requirements. Firstly, you must specify that you want the information when you create the StackTrace. You do so by using a constructor with a Boolean argument set to true. The second prerequisite is that debug information is available. This is present when running the code in the debugger, or when running a compiled executable or library that has been distributed with debug symbols. These are found in program database (PDB) files. If either of these requirements is not met, the three methods return default values.

To see the result of calling GetFileLineNumber, update the ShowCallStack method as shown below and re-run the program. The line numbers may be different to those shown in the comment, depending upon the exact positioning of your source code.

private static void ShowCallStack()
{
    StackTrace trace = new StackTrace(true);
    StackFrame[] frames = trace.GetFrames();
    foreach (StackFrame frame in frames)
    {
        MethodBase info = frame.GetMethod();
        Console.WriteLine("{0}.{1} line {2}"
            , info.ReflectedType.FullName
            , info.Name
            , frame.GetFileLineNumber());
    }
}

/* OUTPUT

Demo.Program.ShowCallStack line 36
Demo.Program.RecursiveCall line 31
Demo.Program.RecursiveCall line 31
Demo.Program.RecursiveCall line 31
Demo.Program.RecursiveCall line 31
Demo.Program.RecursiveCall line 31
Demo.Program.Main line 19
*/

Obtaining the Current Method's Caller

A common task that involves reading the call stack is finding the caller of the current method. You could use the StackTrace class, as shown above, and read the item at index one of the array returned by GetFrames. However, when you only want access to a single stack frame, it is simpler to use a StackFrame constructor. The constructor in question accepts an integer value that specifies the number of items to be skipped from the top of the stack. You can also think of this as the zero-based index of the item you require, where zero returns the currently executing method and passing one returns its caller.

The following code, added to a console application, shows this in action:

static void Main(string[] args)
{
    ShowCaller();
}

private static void ShowCaller()
{
    StackFrame frame = new StackFrame(1);
    Console.WriteLine(frame.GetMethod().Name);
}

/* OUTPUT

Main

*/

Again, if you need access to the source code information, you can add a Boolean parameter with its value set to true:

static void Main(string[] args)
{
    ShowCaller();
}

private static void ShowCaller()
{
    StackFrame frame = new StackFrame(1, true);
    Console.WriteLine("{0} line {1}", frame.GetMethod().Name, frame.GetFileLineNumber());
}

/* OUTPUT

Main line 19

*/
4 November 2012