Bug 58647 - Different behavior between Debug and Release for continuations (Task)
Summary: Different behavior between Debug and Release for continuations (Task)
Alias: None
Product: iOS
Classification: Xamarin
Component: Mono runtime / AOT compiler ()
Version: XI 10.99 (xcode9)
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Zoltan Varga
Depends on:
Reported: 2017-08-08 16:44 UTC by tycho
Modified: 2017-09-13 16:10 UTC (History)
4 users (show)

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

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:

Description tycho 2017-08-08 16:44:18 UTC
I have been building and testing a rather large app on devices and the simulator for a while now; however, when I want to deploy to iPhone|Release, the app crashes. It works fine on iPhone|Debug, iPhoneSimulator|Debug and iPhoneSimulator|Release, just not on iPhone|Release. 

Now the problem is that the trace we get (from Hockeyapp) is; 

at System.Threading.Tasks.Task.AddTaskContinuationComplex (System.Object tc, System.Boolean addBeforeOthers) <0x100229590 + 0x00054> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Threading.Tasks.Task.AddTaskContinuation (System.Object tc, System.Boolean addBeforeOthers) <0x100229830 + 0x0009b> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Threading.Tasks.Task.SetContinuationForAwait (System.Action continuationAction, System.Boolean continueOnCapturedContext, System.Boolean flowExecutionContext, System.Threading.StackCrawlMark& stackMark) <0x100227d00 + 0x00167> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.OnCompletedInternal (System.Threading.Tasks.Task task, System.Action continuation, System.Boolean continueOnCapturedContext, System.Boolean flowExecutionContext) <0x10025b6c0 + 0x0004b> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].UnsafeOnCompleted (System.Action continuation) <0x10025b810 + 0x0002b> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at (wrapper managed-to-native) System.Object:__icall_wrapper_mono_gsharedvt_constrained_call (intptr,intptr,intptr,intptr,intptr)
  at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted[TAwaiter,TStateMachine] (TAwaiter& awaiter, TStateMachine& stateMachine) <0x1002c7970 + 0x0026b> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0x1002586e0 + 0x00028> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_1 (System.Object state) <0x10025aff0 + 0x00053> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) <0x10021c280 + 0x00063> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x100215b70 + 0x0017b> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x100215b30 + 0x0002b> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x10021c1f0 + 0x0005b> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Threading.ThreadPoolWorkQueue.Dispatch () <0x10021a520 + 0x001cb> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0 
  at ObjCRuntime.Runtime.ThreadPoolDispatcher (System.Func`1[TResult] callback) <0x100cb0120 + 0x0003f> in <58a9bd8a3cbb4d0092bc0a767ff66c0f#14060bfac162ea1f2e05021d2b69f424>:0 
  at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0x10021c030 + 0x00087> in <2f4074c3120b4d80802e10af84b67d41#14060bfac162ea1f2e05021d2b69f424>:0

The Exception is in line 4747 of Task.cs which is Task.AddTaskContinuationComplex. 

We kept removing code until we came to a line which basically does; 

var result = await OurService.retrieveWebService(); 

which is then (because of the framework we use) is executed, deep within the framework, by running 

po = await (dynamic)result; 

which is the actual point in our code of the crash. 

The problem is that the codebase is massive and I cannot isolate it any further than this and I cannot send over the code (lawyers etc). 

So what could be the problem that is so different only in iOS and is there any way to debug this somehow? It must be some kind of framework bug right as otherwise it would not be different between Debug/Release on the simulator and Release on the actual iPhone?
Comment 1 Vincent Dondain [MSFT] 2017-08-08 23:23:29 UTC
Please include your full build logs, crash reports (if any), test case (to reproduce) and all version information.

To get full build logs just set the log verbosity to diagnostic at the following locations:
- On Visual Studio for Mac: Preferences > Projects > Build
- On Visual Studio for Windows: Tools > Options > Projects and Solutions > Build and Run

On Visual Studio Windows you also want to add `-v -v -v -v` to the mtouch additional arguments by right-clicking the project in the solution explorer and selecting `Properties`.
Note: this is done automatically on Visual Studio for Mac when the log verbosity is set to diagnostic.

Easiest way to get exact version information:
- On Visual Studio for Mac: "Visual Studio" menu, "About Visual Studio" item, "Show Details" button.
- On Visual Studio for Windows: "Help menu", "About Microsoft Visual Studio" item.
Then copy/paste the version information (you can use the "Copy Information" button).
Comment 2 tycho 2017-08-09 06:19:16 UTC
I think you can ignore everything here as probably no-one would do this; the issue is that we used async void, so it can be reproduced by having an async void method await a bunch of non async void Tasks. This wasn't a good idea anyway and all has been resolved by making that caller method async Task. However, I think the bug should be then; behavior should be identical for Debug & Release. 

For the project it has been fixed, but I still think it's a bug because it only happens on Release builds?
Comment 3 Alex Soto [MSFT] 2017-09-13 16:10:17 UTC
Hello, unfortunately with the provided information is not possible to replicate your issue, if you could provide us with a test case would be awesome. In the meantime, I'll close the bug report and if you for some reason hit it again please feel free to reopen it.