Bug 37040 - Stacktrace no longer preserved
Summary: Stacktrace no longer preserved
Status: RESOLVED FEATURE
Alias: None
Product: Runtime
Classification: Mono
Component: Reflection ()
Version: 4.2.0 (C6)
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: marcos.henrich
URL:
Depends on:
Blocks:
 
Reported: 2015-12-15 20:45 UTC by Neale Ferguson
Modified: 2016-01-07 13:43 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
nunit test case source code (2.32 KB, text/x-csrc)
2015-12-15 20:45 UTC, Neale Ferguson
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FEATURE

Description Neale Ferguson 2015-12-15 20:45:02 UTC
Created attachment 14304 [details]
nunit test case source code

Using the attached program:
- Build with: mcs -debug -out:44389.dll -target:library -lib:System.Runtime.Serialization -r:nunit.framework.dll -r:nunit.core.dll 44389.cs
- Run with 3.10.1 nunit-console4

Result:

NUnit version 2.4.8
Copyright (C) 2002-2007 Charlie Poole.
Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.
Copyright (C) 2000-2002 Philip Craig.
All Rights Reserved.

Runtime Environment - 
   OS Version: Unix 3.0.101.0
  CLR Version: 4.0.30319.17020 ( 3.10.1 (tarball Mon Mar  9 13:34:54 EDT 2015) )

***** StackTraceTest.PreserveStackTraceTest.TestThrowingInnerExceptionPreservingStacktrace
  at StackTraceTest.PreserveStackTraceTest.cat (System.String myParam) [0x00019] in /home/neale/44389.cs:80 
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00054] in /home/BUILD/mono-3.10.1/mcs/class/corlib/System.Reflection/MonoMethod.cs:230 

Tests run: 1, Failures: 0, Not run: 0, Time: 0.030 seconds

Running with 4.3.1:

NUnit version 2.4.8
Copyright (C) 2002-2007 Charlie Poole.
Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.
Copyright (C) 2000-2002 Philip Craig.
All Rights Reserved.

Runtime Environment - 
   OS Version: Unix 3.0.101.0
  CLR Version: 4.6.57.0 ( 4.3.2 (master/9900f81 Tue Dec 15 11:23:41 EST 2015) )

.  at StackTraceTest.PreserveStackTraceTest.TestThrowingInnerExceptionPreservingStacktrace () [0x0004a] in /home/neale/44389.cs:48 
F
Tests run: 1, Failures: 1, Not run: 0, Time: 0.033 seconds

Test Case Failures:
1) StackTraceTest.PreserveStackTraceTest.TestThrowingInnerExceptionPreservingStacktrace :   Expected: True
  But was:  False

at StackTraceTest.PreserveStackTraceTest.TestThrowingInnerExceptionPreservingStacktrace () [0x0007d] in /home/neale/44389.cs:55
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00038] in /home/neale/Mono/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:295

The code preserving the stack trace works in 3.10 but fails in 4.3.
Comment 1 Rodrigo Kumpera 2015-12-21 01:44:47 UTC
Hey Marcos,

Can you take a look at this one
Comment 2 marcos.henrich 2016-01-07 13:38:05 UTC
Hi Neale,

There is something that doesn't feel right on your test, and it seems it was passing previously because there was a problem on mono 3.10.

The test checks the stack trace first without the preserving code and then with the preserving code.

Nonetheless the first does this:
Assert.That(exception.StackTrace.Trim().StartsWith(expectedString));

I check with mono 3.10 and the first case is indeed giving a wrong stack trace.
at StackTraceTest.PreserveStackTraceTest.cat ...
instead of
at StackTraceTest.PreserveStackTraceTest.TestThrowingInnerExceptionPreservingStacktrace

The second check worked on 3.10 because of this bug. This was fixed and mono did not and still doesn't support using ObjectManager to fix exceptions.

I looked into adding support for making your second check work on mono, but it seems that the code you use to preserve exceptions old values is taking advantage of some kind of serialization during exception handling. Adding support for this seems a lot of trouble especially when there is an alternative.

You can still preserve the stack trace by using ExceptionDispatchInfo:
try
{
    methodInfo.Invoke (this, new object[] {"test"});
} catch (TargetInvocationException exception)
{                           System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture (exception.InnerException).Throw ();
}

There is a cleaner better alternative for doing what you want, thus I am marking this as a feature.
Comment 3 marcos.henrich 2016-01-07 13:43:57 UTC
For the record here is my attempt of making this work https://github.com/esdrubal/mono/commit/f8bf6aa52710c434b00cd42225e060af39e448c9