Possible Duplicate:
incorrect stacktrace by rethrow
It is generally accepted that in .NET throw;
does not reset the stack trace but throw ex;
does.
However, in this simple program , I get different line numbers:
void Main()
{
try
{
try
{
Wrapper(); // line 13
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
throw; // line 18
}
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void Wrapper()
{
Throw(); // line 28
}
public void Throw()
{
var x = (string)(object)1; // line 33
}
The output is:
System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.String'. at ConsoleApplication2.Program.Main(String[] args) in C:\long-path\Program.cs:line 13
System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.String'. at ConsoleApplication2.Program.Main(String[] args) in C:\long-path\Program.cs:line 18
Note: The first stack trace contains line 13, the second contains line 18. Additionally, neither line 13 nor line 18 are the lines where the cast is actually happening.
My question now is: In what circumstances does throw;
change the stack trace and in which circumstance doesn't it change the stack trace?
Please note, that this has already been observed, but not answered in general.
UPDATE:
I ran the code above in Debug mode and it yields this:
System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.String'. at ConsoleApplication2.Program.Throw() in C:\long-path\Program.cs:line 33 at ConsoleApplication2.Program.Wrapper() in C:\long-path\Program.cs:line 28 at ConsoleApplication2.Program.Main(String[] args) in C:\long-path\Program.cs:line 13
System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.String'. at ConsoleApplication2.Program.Throw() in C:\long-path\Program.cs:line 33 at ConsoleApplication2.Program.Wrapper() in C:\long-path\Program.cs:line 28 at ConsoleApplication2.Program.Main(String[] args) in C:\long-path\Program.cs:line 18
Please note: The last line number still changes
The reason for this happening is because of method inlining when running in Release mode. If you don't want the Wrapper
and Throw
methods to be inlined in Release mode you could decorate them with the [MethodImpl]
attribute:
[MethodImpl(MethodImplOptions.NoInlining)]
public void Wrapper()
{
Throw();
}
[MethodImpl(MethodImplOptions.NoInlining)]
public void Throw()
{
var x = (string)(object)1;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With