Home Search Contact us About us
Title Processing an Exception to display the call stack.
Summary A short piece of code using reflection to display the call stack in an exception handler.
Contributor John McTainsh
Published 13-Jun-2001
Last updated 13-Jun-2001
Page rating   Be the first to rate this page! Useless Brilliant

Description

When things go bad and an exception occurs it would be nice to display a little more information than just the stack trace. This code segment does just that by using reflection to view the functions on the stack. It displays the functions called and the attribute information for the functions. Unfortunately it is not able to display the values passed in the the functions. That would be really handy! Here the information is simply written to the console. You may wish to write it to a debug file to help in remote diagnostics..

Includes

To use the exception stack reflection we need to include the following namespaces.

    using System.IO;                                // Needed for demo of file exception
    using System.Diagnostics;                       // Access to the Stack trace
    using System.Reflection;                        // Access to Parameter Info 

Here is the code

The following sample uses an exception generated by an AppendText operation that fails because the file name has a * in it. The code iterates through each StackFrame (Function call) and then into each function to extract the parameters. For each function it will display the file name and line number of the function (if known) and the function attributes. 

    try 
    {
        StreamWriter stTextOut = File.AppendText( "*SomeWrite.txt" );
    }
    catch( Exception e )
    {
        // Display the execption error
        Console.Out.WriteLine( "Exception: {0}", e.Message );       

        // Get the Stack trace information
        StackTrace st = new StackTrace( e, true );

        for( int nFrame = 0 ; nFrame < st.FrameCount; nFrame++ )
        {
            // Display File name and line
            StackFrame sf = st.GetFrame( nFrame );
            Console.Out.WriteLine( "\t{0}, {1}", sf.GetFileName(), sf.GetFileLineNumber() );
            MethodBase mb = sf.GetMethod();

            // Extract method return type (There must be a better way)
            string sMethodInfo = mb.ToString();
            int nSpace = sMethodInfo.IndexOf( " " );
            string sReturnType = sMethodInfo.Substring( 0, nSpace );

            //Display the Function name info
            Console.Out.WriteLine( "\t{0} {1}.{2}(", 
                sReturnType, 
                mb.ReflectedType.Name, 
                mb.Name );
            ParameterInfo[] piList = mb.GetParameters();

            //Display the parameters
            foreach( ParameterInfo pi in piList )
            {
                Console.Out.WriteLine( "\t\t{0}\t{1}", pi.ParameterType.Name, pi.Name );
            }
            Console.Out.WriteLine( "\t\t)" );
        }
    }

The output for the above code will look like this. Note, the Main() call appears last and the call that actually threw the exception AddPathList appear first on the list

Exception: Illegal characters found in input.
        <UnknownName>, 0
        Void FileIOPermission.AddPathList(
                FileIOPermissionAccess  access
                String  pathList
                )
        <UnknownName>, 0
        Void FileIOPermission..ctor(
                FileIOPermissionAccess  access
                String  pathList
                )
        <UnknownName>, 0
        Void FileStream..ctor(
                String  path
                FileMode        mode
                FileAccess      access
                FileShare       share
                Int32   bufferSize
                Boolean useAsync
                String  msgPath
                )
        <UnknownName>, 0
        Void FileStream..ctor(
                String  path
                FileMode        mode
                FileAccess      access
                FileShare       share
                Int32   bufferSize
                Boolean useAsync
                )
        <UnknownName>, 0
        Void FileStream..ctor(
                String  path
                FileMode        mode
                FileAccess      access
                FileShare       share
                )
        <UnknownName>, 0
        System.IO.Stream StreamWriter.CreateFile(
                String  path
                Boolean append
                )
        <UnknownName>, 0
        Void StreamWriter..ctor(
                String  path
                Boolean append
                Encoding        encoding
                Int32   bufferSize
                )
        <UnknownName>, 0
        Void StreamWriter..ctor(
                String  path
                Boolean append
                )
        <UnknownName>, 0
        System.IO.StreamWriter File.AppendText(
                String  path
                )
        d:\cs\tryfileio\class1.cs, 28
        Int32 Class1.Main(
                String[]        args
                )
Comments Date
Home Search Contact us About us