Bug 15755 - Awaiting a null object errors silently
Summary: Awaiting a null object errors silently
Status: RESOLVED FEATURE
Alias: None
Product: Runtime
Classification: Mono
Component: JIT ()
Version: 3.2.x
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-10-28 16:35 UTC by James Clancey
Modified: 2013-10-29 14:58 UTC (History)
6 users (show)

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


Attachments
console app source code (397 bytes, application/octet-stream)
2013-10-29 08:52 UTC, Sebastien Pouliot
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 James Clancey 2013-10-28 16:35:33 UTC
The following code should throw a null reference exception. Instead it runs, but never returns. Nothing is outputted to the console. The execution never breaks to show me there was an issue there. This happens in XS and VS.

    public class TestClass
        {
            public Task FooTask()
            {
                return Task.Factory.StartNew(()=>Thread.Sleep(1000));
            }
        }

        TestClass runner;
        public async void RunThisThing()
        {
            runner = null;
            await runner.FooTask();
            Console.WriteLine("finished");
        }
Comment 1 Sebastien Pouliot 2013-10-29 08:51:28 UTC
This is not iOS specific. The same code does not throw anything in a console app. Not sure if it's runtime or compiler related.

$ mcs --version
Mono C# compiler version 3.2.3.0
$ mcs bug15755.cs 
$ mono bug15755.exe 


Next time please attach self-contained test cases: it save times for others and you had one ;-)
Comment 2 Sebastien Pouliot 2013-10-29 08:52:08 UTC
Created attachment 5263 [details]
console app source code
Comment 3 Rolf Bjarne Kvinge [MSFT] 2013-10-29 09:15:23 UTC
This crashes just fine for me in my test project.

The exception is thrown in the console app too, but for some reason nothing is printed to the terminal unless you enable exception output:

> mono --trace=E:all test.exe
[0xa17f81a8:] EXCEPTION handling: System.NullReferenceException: Object reference not set to an instance of an object

"<unnamed thread>" tid=0x0xa17f81a8 this=0x0x658010 thread handle 0x103 state : not waiting owns ()
  at Program/<RunThisThing>c__async0.MoveNext () <0x00057>
  at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start<Program/<RunThisThing>c__async0> (Program/<RunThisThing>c__async0&) <0x00063>
  at Program.RunThisThing () <0x000c3>
  at Program.Main () <0x0001f>
  at (wrapper runtime-invoke) object.runtime_invoke_void (object,intptr,intptr,intptr) <0xffffffff>

[0xb0225000:] EXCEPTION handling: System.NullReferenceException: Object reference not set to an instance of an object

"Threadpool worker" tid=0x0xb0225000 this=0x0x65bdf0 thread handle 0x109 state : not waiting owns ()
  at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.<SetException>m__12 (object) <0x0002f>
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff>

> echo $?
1
Comment 4 Marek Safar 2013-10-29 14:58:48 UTC
The sample is wrong, it may exit before it gets to null dereferencing.

You need something like this which is CONSOLE context specific, iOS behaves very differently!

using System;
using System.Threading;
using System.Threading.Tasks;

public class TestClass
{
	public Task FooTask()
	{
		return Task.Factory.StartNew(()=>Thread.Sleep(1000));
	}
}

class Program {

	TestClass runner;
	static ManualResetEvent mre = new ManualResetEvent (false);

	public async void RunThisThing()
	{
		runner = null;
		await runner.FooTask();
		Console.WriteLine("finished");
		mre.Set ();
	}

	static void Main ()
	{
		new Program ().RunThisThing ();
		mre.WaitOne ();
	}
}


Same with the original problem. We need the context where you start the RunThisThing and how do you check for the error.

Rule #1 of async, NEVER EVER use async void unless you are really sure you understand how it can take your app down.