Bug 30513 - Corrupted stacktrace in exceptions from async void methods
Summary: Corrupted stacktrace in exceptions from async void methods
Status: VERIFIED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: Mono runtime / AOT Compiler ()
Version: 5.1
Hardware: PC Windows
: High major
Target Milestone: 6.0 (C6)
Assignee: Marek Safar
URL:
: 29157 30705 ()
Depends on:
Blocks: 33305
  Show dependency tree
 
Reported: 2015-05-27 14:38 UTC by Grigory (Playtika)
Modified: 2015-09-08 16:50 UTC (History)
11 users (show)

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


Attachments
Test case (30.62 KB, application/zip)
2015-09-08 16:47 UTC, Brendan Zagaeski (Xamarin Team, assistant)
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 Developer Community or GitHub 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:
VERIFIED FIXED

Description Grigory (Playtika) 2015-05-27 14:38:40 UTC
This is NOT a debugger/IDE issue. Exceptions don't contain frames that lead to place where exception is thrown. 

Exception on Android:

SF.Common.AppException: Booooom!
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <IL 0x00011, 0x00078>
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>m__0 (object) <IL 0x00006, 0x0006b>
at Android.App.SyncContext/<Post>c__AnonStorey0.<>m__0 () [0x00000] in /Users/builder/data/lanes/1780/3518c4ce/source/monodroid/src/Mono.Android/src/Android.App/SyncContext.cs:18
at Java.Lang.Thread/RunnableImplementor.Run () [0x0000b] in /Users/builder/data/lanes/1780/3518c4ce/source/monodroid/src/Mono.Android/src/Java.Lang/Thread.cs:36
at Java.Lang.IRunnableInvoker.n_Run (intptr,intptr) [0x00009] in /Users/builder/data/lanes/1780/3518c4ce/source/monodroid/src/Mono.Android/platforms/android-21/src/generated/Java.Lang.IRunnable.cs:71
at (wrapper dynamic-method) object.ea5b4f6a-2b95-410a-99cd-b01215110989 (intptr,intptr) <IL 0x00011, 0x0004b>


Exception on .NET 4.5:
SF.Common.AppException: Booooom!
   at SM.Arena.Dev.ServicePopupController.<Foo>d__1a.MoveNext() in Src\SM\SM.Arena\Dev\ServicePopupController.cs:line 175
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__4(Object state)

This stops all app developers from understanding real reasons that lead app to crash.
Comment 1 Jonathan Pryor 2015-05-27 17:18:51 UTC
Repro:

1. Create a new Xamarin.Android project.

2. Replace the OnCreate() method with the following:

	protected override async void OnCreate (Bundle bundle)
	{
		base.OnCreate (bundle);

		// Set our view from the "main" layout resource
		SetContentView (Resource.Layout.Main);

		await Throws ();
	}

	async Task Throws ()
	{
		Console.WriteLine ("# jonp: Throwing...");
		throw new InvalidOperationException ("DIE DIE DIE!!!");
	}

3. Run the app.

4. Look at `adb logcat`

Results:

> UNHANDLED EXCEPTION:
> System.InvalidOperationException: DIE DIE DIE!!!
> at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <IL 0x00012, 0x00024>
> at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>m__0 (object) <IL 0x00001, 0x0003f>
> at Android.App.SyncContext/<Post>c__AnonStorey0.<>m__0 () <IL 0x0000c, 0x00027>
> at Java.Lang.Thread/RunnableImplementor.Run () <IL 0x00011, 0x0003f>
> at Java.Lang.IRunnableInvoker.n_Run (intptr,intptr) <IL 0x0000a, 0x0003f>
> at (wrapper dynamic-method) object.35f3071c-5d2a-4c6b-bc77-5fa9be6c786c (intptr,intptr) <0x0003b>

Notice that there is no information to suggest where the InvalidOperationException came from; "Throws" doesn't appear anywhere in the logcat output.
Comment 2 Jonathan Pryor 2015-05-27 17:37:27 UTC
@Marek? Zoltan believes that you've possibly fixed something like this already, though mono/mono-4.2.0-pre-branch/6ec454d4 doesn't appear to fix the issue.
Comment 3 Marek Safar 2015-05-28 02:55:02 UTC
The latest mono 4.2 should have it fixed (master commit 1cd83569da1470a2f551fffcbc62b785cecc5959 and there was 1 or 2 before)
Comment 4 Grigory (Playtika) 2015-05-28 03:25:25 UTC
Thank you!
Comment 5 Jonathan Pryor 2015-06-03 11:11:57 UTC
*** Bug 30705 has been marked as a duplicate of this bug. ***
Comment 6 Artur Malendowicz 2015-07-21 07:01:28 UTC
This should be reopened. The bug still exists and blocks Xamarin.Insights from corrent exception reporting.
Comment 7 Marek Safar 2015-07-21 07:25:16 UTC
The issue was fixed in Mono 4.2 based products so be sure you are running them (they should be in preview pretty soon)
Comment 8 Artur Malendowicz 2015-07-21 07:28:32 UTC
So the real fix for me is to get Mono from repo and build it? I have latest assemblies for Xamarin.Android, Xamarin.Core and Mono...
Comment 9 Marek Safar 2015-07-21 07:32:31 UTC
You have to wait for official package or contact Xamarin support
Comment 10 Grigory (Playtika) 2015-07-21 07:57:14 UTC
Basically it is a huge mistake that u didn't prepare a hotfix release for that. Xamarin customers lost millions of users because of unknown crashes in production. 

Good Job :)
Comment 11 Brendan Zagaeski (Xamarin Team, assistant) 2015-07-21 15:36:09 UTC
I am updating this bug with regression information. Since it is a regression, I am also setting the target milestone to the next upcoming service release (Cycle 5 SR4) for an initial assessment of whether the fix can be backported to that release branch.




## Regression status: regression, but a bit of a special case since it seems to be related to the new exception propagation style in XA 5.1

"BAD":  XA 5.1.5.2   (2e8568c)
"BAD":  XA 5.1.0.115 (d23da36)
"GOOD": XA 4.20.2.1  (86274ad)




## Example "expected result" from XA 4.20 (excerpt from the logcat output)

> I/MonoDroid( 2436): UNHANDLED EXCEPTION:
> I/MonoDroid( 2436): System.InvalidOperationException: DIE DIE DIE!!!
> I/MonoDroid( 2436):   at AndroidApp1.MainActivity+<Throws>c__async1.MoveNext () [0x00022] in /private/tmp/Working/AndroidApp1/AndroidApp1/MainActivity.cs:31 
> I/MonoDroid( 2436): --- End of stack trace from previous location where exception was thrown ---
> I/MonoDroid( 2436):   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
> I/MonoDroid( 2436):   at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <filename unknown>:0 
> I/MonoDroid( 2436):   at AndroidApp1.MainActivity+<OnCreate>c__async0.MoveNext () [0x00043] in /private/tmp/Working/AndroidApp1/AndroidApp1/MainActivity.cs:25 
> 




## Partial "workaround"

It is possible to revert to the old exception behavior from Xamarin.Android 4.x on Xamarin.Android 5.x. In particular, you can set the XA_BROKEN_EXCEPTION_TRANSITIONS environment variable to "true" [1]. (See also [2].)

[1] http://developer.xamarin.com/guides/android/advanced_topics/environment/
[2] http://developer.xamarin.com/releases/android/xamarin.android_5/xamarin.android_5.1/#Cross-VM_Exception_Propagation


This is only a partial workaround because the new exception propagation style introduced by XA 5.1 is preferable for released apps. Reverting to the old propagation style is a suboptimal workaround.



### Example result in XA 5.1.5.2 after the workaround (excerpt from the logcat output)

> E/mono    ( 1939): Unhandled Exception:
> E/mono    ( 1939): System.InvalidOperationException: DIE DIE DIE!!!
> E/mono    ( 1939):   at AndroidApp1.MainActivity+<Throws>c__async1.MoveNext () [0x00022] in /private/tmp/Working/AndroidApp1/AndroidApp1/MainActivity.cs:31 
> E/mono    ( 1939): --- End of stack trace from previous location where exception was thrown ---
> E/mono    ( 1939):   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in <filename unknown>:0 
> E/mono    ( 1939):   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0004e] in <filename unknown>:0 
> E/mono    ( 1939):   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in <filename unknown>:0 
> E/mono    ( 1939):   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in <filename unknown>:0 
> E/mono    ( 1939):   at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <filename unknown>:0 
> E/mono    ( 1939):   at AndroidApp1.MainActivity+<OnCreate>c__async0.MoveNext () [0x00043] in /private/tmp/Working/AndroidApp1/AndroidApp1/MainActivity.cs:25
Comment 12 Peter Collins 2015-07-21 16:48:04 UTC
*** Bug 29157 has been marked as a duplicate of this bug. ***
Comment 13 Artur Malendowicz 2015-07-21 20:23:04 UTC
After adding .txt file as AndroidEnvironment with XA_BROKEN_EXCEPTION_TRANSITIONS flag set to true, nothing changes.
Comment 14 Brendan Zagaeski (Xamarin Team, assistant) 2015-07-22 01:28:50 UTC
Shoot, yup. It looks like Xamarin.Insights only pulls in the log output lines that are tagged with "MonoDroid" (at least by default), and on XA 5.1 (even with the workaround from comment 11) those lines still do not mention "AndroidApp1.MainActivity+<Throws>".

I played around a bit with trying to use an invocation of `Insights.Report()` called in an event handler for the `AppDomain.CurrentDomain.UnhandledException` event. The local log file for the app showed that "[Xamarin.Insights]" was capturing the additional desired "[mono]" log lines, but I couldn't seem to get that information to upload to the Xamarin.Insights server. There might still be a way to change the default exception processing that is done by Xamarin.Insights for unhandled exceptions, but it might be quite tricky or even impractical.

_Handled_ exceptions from async methods that are reported to Insights via try/catch + `Insights.Report()` do appear to include the desired "at AndroidApp1.MainActivity+<Throws>c__async1.MoveNext ()" line of the stack trace (even without XA_BROKEN_EXCEPTION_TRANSITIONS). So in theory an alternate (if somewhat "brute force") workaround might be to wrap every awaited async method in a try/catch and use `Insights.Report()` to send the exception to Insights.
Comment 15 Artur Malendowicz 2015-07-22 11:25:15 UTC
Okey guys, so I have found workaround for this bug, here is step by step what to do to handle it and let Xamarin.Insights work.
1.Add text file to Android project(name doesn't matter)and set it from "Content" in properties to "AndroidEnvironment"

2.In the text file you created add that flag: XA_BROKEN_EXCEPTION_TRANSITIONS=true

3.Then add android exception global handler in your droid project, it will handle Android exceptions which normally crashes application before your Xamarin.Insights(or other report tool)would be able to do some work.

>AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) => 
>    {
>         args.Handled = true;
>    }

And voila, the Xamarin.Insights is ready to work for you :)
Comment 16 Artur Malendowicz 2015-07-22 11:26:20 UTC
Of course thanks goes to Brendan Zagaeski.
Comment 18 Abhishek 2015-08-11 12:30:16 UTC
I have checked this issue with XA 4.20.2.1 and showing correct behavior.

Exception output: https://gist.github.com/Abhishekk360/a6090c169fdf9a785d50

I have checked this issue with XA 5.1.0.115 and I am able to reproduce this issue.

Exception Output:https://gist.github.com/Abhishekk360/b8ed822f8f490cd15298

I have checked this issue with latest C5 Trunk build mono-android-5.1.4-34_a4f3627bb6a2615c481896899e5c09a45e56db9c but still I am getting the same behavior

Screencast:http://www.screencast.com/t/FoH9idOS
Exception Output:https://gist.github.com/Abhishekk360/7e50097d23a516b57941
adb Logcat: https://gist.github.com/Abhishekk360/1973348d611f574158f9

I have checked this issue with latest master build mono-android-5.1.99-567_df8d794b893cdc86b5ea25bf7180f8a523d93559 but still getting the same behavior

Exception Output: https://gist.github.com/Abhishekk360/8886890409ec5c2f641d
adb logcat: https://gist.github.com/Abhishekk360/cc706467bdd3c89f9c1e

Could you please let me know with which build I have to use to verify this issue?

As if now I am reopening this issue.
Comment 19 PJ 2015-08-12 16:36:30 UTC
Unfortunately, the fix is unable to be backported to Mono 4.0.x, and the full fix will only be available as part of Mono 4.2.0. Mono 4.2.0 will be included in Xamarin.Android 5.2.0, all part of the Cycle 6 release.

We currently estimate that there will be public Alphas of Cycle 6 available at the end of August or in early September.

Updating target milestone.
Comment 20 Oleg 2015-09-02 05:45:16 UTC
Alpha is out and bug is not fixed yet?
Comment 21 Peter Collins 2015-09-02 13:11:41 UTC
It looks like there was a bit of a mixup here. We were never able to confirm that this fix was working as expected using a monodroid build that included mono 4.2. 

@Marek can you take another look at this?
Comment 22 Marek Safar 2015-09-03 07:53:43 UTC
This issue was fixed in C6 based products. If you still have failing tests please attach it so we can repro it with C6 version
Comment 23 Brendan Zagaeski (Xamarin Team, assistant) 2015-09-08 16:47:03 UTC
Created attachment 12831 [details]
Test case

## Verification status: the test case from comment 2 is verified fixed in the current Alpha version

GOOD: Xamarin.Android 5.1.99.653 (cfa43bb5), which I believe is based on mono/mono-4.2.0-branch 9b990f2.




## Steps to verify

Run the attached test case (based on comment 2).

(For example, use "Run -> Start Without Debugging" in Xamarin Studio on Mac. I tested in both the Debug and Release configuration.)

(I also checked the results adding Xamarin.Insights. I tested both the attached case and the test case attached to the closely related Bug 33305. Both test cases produced the desired results.)




## Results

The stack trace in the `adb logcat` output contains the expected top frame of the stack trace (it mentions "Throws"):

> System.InvalidOperationException: DIE DIE DIE!!!
>   at AndroidApp1.MainActivity+<Throws>c__async1.MoveNext () <0x91861d38 + 0x00073>
> --- End of stack trace from previous location where exception was thrown ---
>   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0x91869b28 + 0x0002b>
>   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) <0x918696f0 + 0x000b3>
>   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) <0x91869590 + 0x0007f>
>   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) <0x91869540 + 0x00033>
>   at System.Runtime.CompilerServices.TaskAwaiter.GetResult () <0x91869518 + 0x00013>
>   at AndroidApp1.MainActivity+<OnCreate>c__async0.MoveNext () <0x91860d20 + 0x0011b>


(This same correct stack trace also appears in the Xamarin.Insights web portal when I add Xamarin.Insights integration to the test case.)




## Additional version info (brief)

### Devices tested

- Xamarin Android Player 0.4.4, Nexus 4, Android 4.4, x86 emulator

- LG Optimus L9, Android 4.1.2, armeabi-v7a hardware device
Comment 24 Brendan Zagaeski (Xamarin Team, assistant) 2015-09-08 16:49:02 UTC
Marking as resolved as per comment 23.
Comment 25 Brendan Zagaeski (Xamarin Team, assistant) 2015-09-08 16:50:10 UTC
Also as per Comment 23, I am marking this bug as "verified" against the Xamarin.Android 5.2 (Cycle 6) target milestone. Accordingly, this exact bug report can now be considered closed. Any reports of similar problems on Xamarin.Android 5.1.99.653 or higher may be filed separately.


In particular, if any customer with a Business license or higher comes across this bug while attempting to solve a similar problem on Xamarin.Android 5.1.99.653 or higher, please contact Xamarin Support via email [1]. The support team will request additional details and then file a new bug if appropriate.

[1] https://kb.xamarin.com/customer/portal/articles/1632104-how-do-i-contact-xamarin-for-support-



If you have an Indie, Starter, Trial, or academic license, feel free to file a new bug report directly.



Thanks!

Brendan
Xamarin Customer Support