stack trace has incorrect information

  • Thread starter Thread starter Andy Fish
  • Start date Start date
A

Andy Fish

Hi,

in my c# code I have something like this:

try {
...
} catch (Exception ex) {
...
throw ex;
}

It seems to catch and re-throw the exception OK, but the stack trace
contains the line I re-threw the exception, not the line it was generated
on.

anyone else seen this bug? are there any workarounds?

Andy
 
Andy Fish said:
in my c# code I have something like this:

try {
...
} catch (Exception ex) {
...
throw ex;
}

It seems to catch and re-throw the exception OK, but the stack
trace contains the line I re-threw the exception, not the line it was
generated on.

anyone else seen this bug? are there any workarounds?

It is not a bug because the stack trace shows where the exception has been
thrown, and this is done in your "throw ex" line. You could throw a new
exception and pass ex as the "InnerException" to the new exception.


--
Armin

How to quote and why:
http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html
 
Andy Fish said:
in my c# code I have something like this:

try {
...
} catch (Exception ex) {
...
throw ex;
}

It seems to catch and re-throw the exception OK, but the stack trace
contains the line I re-threw the exception, not the line it was generated
on.

anyone else seen this bug? are there any workarounds?

It's not a bug. The way to change the behaviour is to use throw;
instead of throw ex;
 
Jon Skeet said:
It's not a bug. The way to change the behaviour is to use throw;
instead of throw ex;


Before posting my reply, I tried "throw" only, but the error line is still
the one containing the throw statement, not the one of the original
exception.
 
Armin Zingler said:
Before posting my reply, I tried "throw" only, but the error line is still
the one containing the throw statement, not the one of the original
exception.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

Bear in mind that inlining can affect stack traces, so be careful of
that - you can apply the MethodImplAttribute with
MethodImplOptions.NoInlining for test purposes to make sure that's not
what's going on.
 
It's not a bug. The way to change the behaviour is to use throw;
instead of throw ex;

This seems very strange behaviour to me. I would have thought the exception
object is supposed to encapsulate everything about the orignal error -
especially the point where it happened (i.e. where it was constructed). If I
wanted to record the point where I re-threw it, then I would use "throw new
Exception(ex)"

Anyway, I have tried just "throw" on it's own and it seems to partially
work. Unfortunately the stack trace still shows the 'throw' statement inside
my method (rather than the line inside my function called the method that
caused the error. however, because the deeper stack trace is intact, it's
fairly easy to narrow it down.

Andy
 
Jon Skeet said:
Could you post a short but complete program which demonstrates the
problem?


/I/ don't have a problem with it, so I think Andy should do this. :-)
 
This seems very strange behaviour to me. I would have thought the
exception
object is supposed to encapsulate everything about the orignal error -
especially the point where it happened (i.e. where it was constructed). If I
wanted to record the point where I re-threw it, then I would use "throw new
Exception(ex)"

The behavior is supposed to be as follows:

throw;

....is actually a rethrow of the original exception, and the stack trace is
*supposed* to be left unchanged so that it shows the original line of code
on which the exception occurred. However, there is a bug in the current
version of the framework so that it actually resets the stack trace to the
LOC to the throw statement.

throw ex; //

throw new Exception("Your message here",ex);

set the stack trace to the LOC of the throw statement. The difference
between the two is that in the first case the stack trace is intentionally
set to the LOC of the throw statement - since this deliberately loses
information there is no valid reason to use this form unless you
intentionally want to obscure the problem; instead, use the naked throw
statement (when they fix the bug the original stack trace will remain).

The latter form of throw is an example of catch-wrap-throw. A new exception
object is created with the stack trace set to the LOC of the throw
statement, but the original exception object is left unchanged so that the
original LOC that caused the exception is preserved.

Personally I recommend the latter form as it adds context information and
loses nothing.
 
Back
Top