Bug 5963 - Null reference exceptions are uncatchable
Summary: Null reference exceptions are uncatchable
Status: RESOLVED FIXED
Alias: None
Product: Runtime
Classification: Mono
Component: General ()
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Jonathan Chambers
URL:
Depends on:
Blocks:
 
Reported: 2012-07-03 09:45 UTC by Ruan PA
Modified: 2012-07-24 07:11 UTC (History)
5 users (show)

Tags:
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 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 FIXED

Description Ruan PA 2012-07-03 09:45:29 UTC
We're using an embedded Mono build for C# scripting in CryENGINE, and invoking managed methods with calls to mono_runtime_invoke_array. We also have an exception handler that works most of the time via a subscription to the appdomain's UnhandledException event.

However, null reference exceptions in managed code cause hard crashes in unmanaged code, even when surrounded with try/catch. I've also reproduced this in our minimal embedded sample (https://github.com/inkdev/Embedded-Mono-Sample) with this very basic test case in the ClassLibraryManager ctor.

try
{
	object test = null;
	test.GetType();
}
catch(Exception ex)
{
	Console.WriteLine(ex.ToString());
}
Comment 1 Zoltan Varga 2012-07-05 11:12:16 UTC
Setting the env variable MONO_DEBUG to 'explicit-null-checks' might work around this.

ie. do
setenv ("MONO_DEBUG", "explicit-null-checks") before initalizing mono.
Comment 2 Ruan PA 2012-07-05 12:39:48 UTC
Cheers for taking a look at this. Unfortunately I'm still crashing with a null deref and the following stack:

> mono-2.0.dll!mono_jit_runtime_invoke(_MonoMethod * method, void * obj, void * * params, MonoObject * * exc) Line 5920
 mono-2.0.dll!mono_runtime_invoke(_MonoMethod * method, void * obj, void * * params, MonoObject * * exc) Line 2809
 mono-2.0.dll!mono_runtime_object_init(MonoObject * this) Line 108
 MonoEmbedSample.exe!CMonoApplication::CMonoApplication() Line 23


This is the relevant portion of our test case ctor in C++, and I'm using the same C# as above.

SetEnvironmentVariable("MONO_DEBUG", "explicit-null-checks");
mono_set_dirs(PathUtil::GetLibDirectory().c_str(), PathUtil::GetConfigDirectory().c_str());
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
m_pRootDomain = mono_jit_init_version("MonoApplication", "v4.0.30319");
Comment 3 Ruan PA 2012-07-05 13:18:33 UTC
Hunting through the mailing lists, I discovered that mono_jit_parse_options requires --soft-breakpoints for this to work.

I'd mark this as resolved but I have no idea which category to use seeing as it's not really 'fixed' (insofar as this appears to be by design). Would there be performance implications if this were to be made the default?
Comment 4 Zoltan Varga 2012-07-05 16:32:41 UTC
I'm not sure why that setenv() call doesn't work, it should. Passing --soft-breakpoints is fine workaround too, if it works. IMHO, this problem is not fixed, mono shouldn't crash since we install our own exception handler for nullrefs, this works on linux, and should work on windows too.
Comment 5 Jonathan Chambers 2012-07-18 13:51:40 UTC
If I run the sample code with the exception in the ctor it runs fine. I get:

System.NullReferenceException: Object reference not set to an instance of an object
  at ClassLibraryNamespace.ClassLibraryManager..ctor () [0x00000] in <filename unknown>:0

Note that you cannot run the exe with VS attached or the NullReferenceExceptions will look like AccessViolations in native code and the debugger will not proceed. There is a workaround to this, but I haven't committed it yet.

Were you hitting the issue only when running with VS attached?
Comment 6 Ruan PA 2012-07-18 14:23:05 UTC
Aha, that was indeed the issue, thanks for the heads-up on the access violations! The workaround proposed above has kept us going in the meantime (we're almost constantly running via VS) but it's good to know there's a fix in the works.

Incidentally, are there any major performance implications to using soft breakpoints?
Comment 7 Jonathan Chambers 2012-07-18 14:43:08 UTC
FYI, if you want to run in VS replace 

mono_old_win_toplevel_exception_filter = SetUnhandledExceptionFilter(seh_handler);

with 

AddVectoredExceptionHandler (1, seh_handler)

And replace

if (mono_old_win_toplevel_exception_filter) SetUnhandledExceptionFilter(mono_old_win_toplevel_exception_filter);

with 

RemoveVectoredExceptionHandler (seh_handler)


I haven't done this in master yet as a) it's XP only and we sort of support Win2k b) I need to make sure exception chaining APIs still work.
Comment 8 Jonathan Chambers 2012-07-18 14:45:13 UTC
Zoltan can comment further, but performance implications of 'explicit-null-checks' are that you'll get a NULL check emitted before each reference access to avoid access violations.
Comment 9 Zoltan Varga 2012-07-18 17:33:33 UTC
Generated code will get a bit bigger and a bit slower.
Comment 10 Jonathan Chambers 2012-07-24 07:11:44 UTC
Closing this as the exceptions actually are catchable.