stack trace has incorrect information

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
 
A

Armin Zingler

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
 
J

Jon Skeet [C# MVP]

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;
 
A

Armin Zingler

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.
 
J

Jon Skeet [C# MVP]

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.
 
A

Andy Fish

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
 
A

Armin Zingler

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. :)
 
D

David Levine

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top