Bug 7463 - Async method with generics crashes
Summary: Async method with generics crashes
Status: RESOLVED DUPLICATE of bug 7574
Alias: None
Product: Runtime
Classification: Mono
Component: JIT ()
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on: 7574
Blocks:
  Show dependency tree
 
Reported: 2012-09-26 05:59 UTC by Virgile Bello
Modified: 2012-10-02 03:01 UTC (History)
4 users (show)

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


Attachments
TestMonoAsyncGenerics.cs reproducing issue + generated MCS and CSC executables (if needed) (5.68 KB, application/octet-stream)
2012-09-26 06:00 UTC, Virgile Bello
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 DUPLICATE of bug 7574

Description Virgile Bello 2012-09-26 05:59:49 UTC
I have some issues when using function compiled with async+generics.
The attached code, when compiled with mono compiler, works fine (TestMonoAsyncGenerics-MCS.exe).

However, when compiled with MS compiler, it doesn't work with mono VM (TestMonoAsyncGenerics-CSC.exe)
Generated JIT code is invalid (parameters are not copied properly into the async generic struct -- trying to use them result in a crash because objects that should be valid are null). Attached code show this issue in AsyncWithAwait.

On top of this, if the async method has no await, it will generates an exception.
Attached code show this issue in AsyncNoAwait. I suppose this is related to previous bug.

Expected output, when running TestMonoAsyncGenerics-CSC.exe (works fine with MS.NET VM)
AsyncWithAwait 32
AsyncNoAwait 32

But I get this with mono:
AsyncWithAwait 0
AsyncNoAwait 32
Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object
  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.Object].SetResult (System.Object result) [0x00000] in <filename unknown>:0

Of course I just show the issue with a int, but if it's a pointer it will be null and crash when using it as well.

Reproduced issue with both freebsd x64 and windows official beta package (2.11.4).
Comment 1 Virgile Bello 2012-09-26 06:00:43 UTC
Created attachment 2618 [details]
TestMonoAsyncGenerics.cs reproducing issue + generated MCS and CSC executables (if needed)
Comment 2 Zoltan Varga 2012-09-28 20:05:24 UTC
This is probably due to the differences between the class library support the generated async code depends on.
mareks ?
Comment 3 Virgile Bello 2012-09-29 00:34:52 UTC
Just so you know, when I investigated I had more the feeling about codegen issues at assembly level (parameters get shifted/lost in the stack).

Even if class library was bad, the point is it was trying to dereference a pointer at a location where there was nothing (a variable supposed to be on the stack but it was not). Except if unsafe code in that class library is wrong, it should not be possible, right?

You can try the behavior by replacing the int with a class and trying to access it (I did a showcase with a int, but with a class it will just end up pointing on invalid memory).
Comment 4 Zoltan Varga 2012-09-29 02:03:56 UTC
There is an AsyncTaskMethodBuilder<T> struct on the stack, and the code inside SetResult () tries to
do this call:
			if (!task.TrySetResult (null))
The 'task' field is null, which causes the NullReferenceException.
Comment 5 Virgile Bello 2012-09-29 03:16:51 UTC
Ha yes, sorry, I thought about the first issue (display 0 instead of 32, or crash if class).
About the second issue (with no real async), it's most likely class library as you said.
Comment 6 Marek Safar 2012-10-01 14:42:56 UTC
Zolta, it's generic sharing bug.
Comment 7 Zoltan Varga 2012-10-01 20:03:01 UTC
It looks like it is, it works with -O=-gshared.
Comment 8 Marek Safar 2012-10-02 03:01:18 UTC
Created simpler test case as 7574

*** This bug has been marked as a duplicate of bug 7574 ***