19

How would one display what line number caused the error and is this even possible with the way that .NET compiles its .exes?

If not is there an automated way for Exception.Message to display the sub that crapped out?

try
{
  int x = textbox1.Text;
}
catch(Exception ex)
{
     MessageBox.Show(ex.Message);
}
bluish
  • 26,356
  • 27
  • 122
  • 180
Crash893
  • 11,428
  • 21
  • 88
  • 123

7 Answers7

48

Use ex.ToString() to get the full stack trace.

You must compile with debugging symbols (.pdb files), even in release mode, to get the line numbers (this is an option in the project build properties).

bluish
  • 26,356
  • 27
  • 122
  • 180
Steven A. Lowe
  • 60,273
  • 18
  • 132
  • 202
  • 1
    If it is a web project and you want to deploy pdbs to the server - in project options in the Package/Publish Web section uncheck "Exclude generated debug symbols". – Zar Shardan Feb 06 '17 at 12:18
  • 1
    Can someone provide clarification on "compile with debugging symbols"? My project has 'Define DEBUG constant', 'Define TRACE constant', and 'Debug info: full', and I'm not getting line numbers. MSDN says, "click the Build tab in the left pane of the property page, then select the check boxes for the compiler settings you want to enable. Clear the check boxes for settings you want to disable." Helpful. – omJohn8372 Jan 02 '18 at 16:49
  • I got it to work in release mode only when I unchecked optimize code – Kobbe Apr 18 '19 at 14:25
31

To see the stacktrace for a given Exception, use e.StackTrace

If you need more detailed information, you can use the System.Diagnostics.StackTrace class (here is some code for you to try):

try
{
    throw new Exception();
}
catch (Exception ex)
{
    //Get a StackTrace object for the exception
    StackTrace st = new StackTrace(ex, true);

    //Get the first stack frame
    StackFrame frame = st.GetFrame(0);

    //Get the file name
    string fileName = frame.GetFileName();

    //Get the method name
    string methodName = frame.GetMethod().Name;

    //Get the line number from the stack frame
    int line = frame.GetFileLineNumber();

    //Get the column number
    int col = frame.GetFileColumnNumber();
}

This will only work if there is a pdb file available for the assembly. See the project properties - build tab - Advanced - Debug Info selection to make sure there is a pdb file.

Gabriel McAdams
  • 56,921
  • 12
  • 61
  • 77
  • 1
    Why would you get the first stack frame? Wouldn't you rather be interested in the last stack frame? i.e. StackFrame frame = st.GetFrame(st.FrameCount - 1) – Dewald Swanepoel Jan 15 '15 at 09:28
  • I tried using this in a WCF web service and the line number it returns is always 0. This is in debug mode with the .pdb file present. – Michael S. Miller May 04 '16 at 18:05
  • I'm having issues getting the PDB file to be loaded by my DLL - do I just need to ensure they're in the same directory? –  Jun 09 '20 at 18:42
4

If you use 'StackTrace' and include the .pdb files in the working directory, the stack trace should contain line numbers.

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
0
string lineNumber=e.StackTrace.Substring(e.StackTrace.Length - 7, 7);
Ahmed Elzeiny
  • 67
  • 1
  • 3
0

this way you can Get Line number from Exception

public int GetLineNumber(Exception ex)
{

    const string lineSearch = ":line ";
    var index = ex.StackTrace.LastIndexOf(lineSearch);
    int ln=0;
    if (index != -1)
    {


        var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
        string lnum = System.Text.RegularExpressions.Regex.Match(lineNumberText, @"\d+").Value;
        int.TryParse(lnum,out ln);

    }
    return ln;
}
0

Line numbers will be included in the stack trace if the library which generated the exception is compiled with debug symbols. This can be a separate file (*.pdb) or embedded in the library.

For .NET Core, .NET 5 and later, to have full exception line numbers in release builds, configure the project as follows:

<PropertyGroup>    
  <DebugSymbols>true</DebugSymbols>
  <DebugType>embedded</DebugType>

    <!-- Only enable the following if the line numbers mismatch -->
    <!--<Optimize>false</Optimize>-->
    
    <!--
      Additional properties which may impact how printed line numbers match the source code line numbers are listed here:
      https://learn.microsoft.com/en-us/dotnet/core/run-time-config/compilation
    -->
</PropertyGroup>

The above configuration will include debug symbols directly with the built files, which can be published as nugets.

An alternative to the above is to restore debug packages together with the main nuget packages, which is currently not yet supported: https://github.com/NuGet/Home/issues/9667

Now get the exception line numbers:

try
{
    throw new Exception();
}
catch (Exception ex)
{
    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(0);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();
}
aleksander_si
  • 1,021
  • 10
  • 28
0

Is it possible to simply get the top frame from the StackTrace exposed by ex?

try
{
    throw new Exception();
}
catch (Exception ex)
{
    // Get the top stack frame
    var frame = ex.StackTrace().GetFrame(0);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();
}