Bug 16461 - when Delegate.DynamicInvoke is called from multiple threads at the same time NullReferenceException is thrown
Summary: when Delegate.DynamicInvoke is called from multiple threads at the same time ...
Status: RESOLVED FIXED
Alias: None
Product: Runtime
Classification: Mono
Component: General ()
Version: 3.2.x
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-11-26 09:59 UTC by Marian Salaj
Modified: 2014-01-08 10:55 UTC (History)
4 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 Marian Salaj 2013-11-26 09:59:42 UTC
Test code:

       static Action action = new Action(() => { });

        static void Thread()
        {
            action.DynamicInvoke(null);
        }

        private static void Main()
        {
            Thread t1 = new Thread(Thread);
            t1.Start();

            Thread t2 = new Thread(Thread);
            t2.Start();
        }


This test code sometimes (~10%) throws NullReferenceException on linux, on windows this code seams to be running fine.

Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00014] in /home/user/mono-git/mcs/class/corlib/System.Reflection/MonoMethod.cs:209 
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /home/user/mono-git/mcs/class/corlib/System.Reflection/MethodBase.cs:114 
  at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x000d5] in /home/user/mono-git/mcs/class/corlib/System/Delegate.cs:424 
  at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x00018] in /home/user/mono-git/mcs/class/corlib/System/MulticastDelegate.cs:70 
  at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] in /home/user/mono-git/mcs/class/corlib/System/Delegate.cs:398 
  at Test.Program.Thread () [0x00000] in <filename unknown>:0 
  at System.Threading.Thread.StartInternal () [0x00016] in /home/user/mono-git/mcs/class/corlib/System.Threading/Thread.cs:691 

mono -V
Mono Runtime Engine version 3.2.7 (master/e0f8c2c Tue Nov 26 15:27:22 CET 2013)
Copyright (C) 2002-2013 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug 
        LLVM:          supported, not enabled.
        GC:            sgen


It looks like a private field "default_binder" in class System.Reflection.Binder has null value. 
But I don't know how this could be when this field is static readonly and is initialized.

static readonly Binder default_binder = new Default ();
Comment 1 Zoltan Varga 2013-11-27 04:22:26 UTC
Can't reproduce this.
Comment 2 Marian Salaj 2013-11-27 09:32:20 UTC
I have done some debugging. Exception is thrown on this line in MonoMethod.cs:
binder.ConvertValues (parameters, pinfo, culture, (invokeAttr & BindingFlags.ExactBinding) != 0); 

because binder has null value assigned from static readonly field "default_binder" (Binder.cs).
This field has null value because static constructor of Binder class was not yet called. If I understand this stack
traces correctly then thread 4 is just JITing the constructor System.Reflection.Binder:.cctor ()


[New Thread 0x7ffff4c07700 (LWP 8471)]
[New Thread 0x7ffff49bf700 (LWP 8472)]
[New Thread 0x7fffeffff700 (LWP 8473)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff49bf700 (LWP 8472)]
0x00007ffff4dc7e77 in System.Reflection.MonoMethod:Invoke (this=..., obj=null, invokeAttr=Default, binder=..., parameters=null, culture=...) at <unknown>:230
230     <unknown>: No such file or directory.
        in <unknown>
(gdb) info threads
  Id   Target Id         Frame 
  4    Thread 0x7fffeffff700 (LWP 8473) "mono" 0x0000000000417615 in mono_get_optimizations_for_method (method="System.Object:runtime_invoke_void ()", default_opt=370239999) at mini.c:6318
* 3    Thread 0x7ffff49bf700 (LWP 8472) "mono" 0x00007ffff4dc7e77 in System.Reflection.MonoMethod:Invoke (this=..., obj=null, invokeAttr=Default, binder=..., parameters=null, culture=...)
    at <unknown>:230
  2    Thread 0x7ffff4c07700 (LWP 8471) "mono" 0x00007ffff75423c0 in sem_wait () from /lib/libpthread.so.0
  1    Thread 0x7ffff7fed780 (LWP 8436) "mono" 0x00007ffff75401fc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0



(gdb) bt
#0  0x00007ffff4dc7e77 in System.Reflection.MonoMethod:Invoke (this=..., obj=null, invokeAttr=Default, binder=..., parameters=null, culture=...) at <unknown>:230
#1  0x00007ffff4dc3c14 in System.Reflection.MethodBase:Invoke (this=..., obj=null, parameters=null) from /home/user/mono/lib/mono/2.0/mscorlib.dll.so
#2  0x00007ffff4d1caa7 in System.Delegate:DynamicInvokeImpl (this=..., args=null) at <unknown>:424
#3  0x00007ffff4d34411 in System.MulticastDelegate:DynamicInvokeImpl (this=..., args=null) from /home/user/mono/lib/mono/2.0/mscorlib.dll.so
#4  0x00007ffff4d1c8d3 in System.Delegate:DynamicInvoke (this=..., args=null) from /home/user/mono/lib/mono/2.0/mscorlib.dll.so
#5  0x00000000400142c1 in ?? ()
#6  0x00007ffff49bebd0 in ?? ()
#7  0x00007ffff4efe988 in System.Threading.Thread:StartInternal (this=...) at <unknown>:693
#8  0x0000000040014273 in ?? ()
#9  0x000000000062e810 in ?? ()
#10 0x0000000000000018 in ?? ()
#11 0x0000000000000000 in ?? ()


(gdb) thread 4
[Switching to thread 4 (Thread 0x7fffeffff700 (LWP 8473))]
#0  0x0000000000417615 in mono_get_optimizations_for_method (method="System.Object:runtime_invoke_void ()", default_opt=370239999) at mini.c:6318
6318    {
(gdb) bt
#0  0x0000000000417615 in mono_get_optimizations_for_method (method="System.Object:runtime_invoke_void ()", default_opt=370239999) at mini.c:6318
#1  0x000000000041fcec in mono_jit_compile_method (method="System.Object:runtime_invoke_void ()") at mini.c:6187
#2  0x000000000042044a in mono_jit_runtime_invoke (method="System.Reflection.Binder:.cctor ()", obj=0x0, params=<optimized out>, exc=0x7fffefffe568) at mini.c:6516
#3  0x00000000005aa5db in mono_runtime_invoke (method="System.Reflection.Binder:.cctor ()", obj=0x0, params=0x0, exc=0x7fffefffe568) at object.c:2827
#4  0x00000000005b1cb8 in mono_runtime_class_init_full (vtable=vtable("System.Reflection.Binder"), raise_exception=1) at object.c:376
#5  0x000000000041ac16 in mono_resolve_patch_target (method=0x0, domain=0x9f9660, code=<optimized out>, patch_info=0xaabb90, run_cctors=0) at mini.c:3412
#6  0x000000000049b48c in load_method (domain=<optimized out>, amodule=0xa04380, image=<optimized out>, method=<optimized out>, token=<optimized out>, method_index=<optimized out>)
    at aot-runtime.c:3369
#7  0x000000000049c664 in mono_aot_get_method_from_vt_slot (domain=0x9f9660, vtable=<optimized out>, slot=69) at aot-runtime.c:2016
#8  0x00000000004aa4f3 in mono_vcall_trampoline (regs=0x7fffefffe9f8, code=0x7ffff4dc3c14 "H\203\304", <incomplete sequence \303>, slot=69, tramp=0x400132c6 "\350\265\t\377\377\004E")
    at mini-trampolines.c:744
#9  0x0000000040003de6 in ?? ()
#10 0x00007ffff4dc3c14 in System.Reflection.MethodBase:Invoke (this=..., obj=null, parameters=null) from /home/user/mono/lib/mono/2.0/mscorlib.dll.so
#11 0x00007ffff4d1caa7 in System.Delegate:DynamicInvokeImpl (this=..., args=null) at <unknown>:424
#12 0x00007ffff4d34411 in System.MulticastDelegate:DynamicInvokeImpl (this=..., args=null) from /home/user/mono/lib/mono/2.0/mscorlib.dll.so
#13 0x00007ffff4d1c8d3 in System.Delegate:DynamicInvoke (this=..., args=null) from /home/user/mono/lib/mono/2.0/mscorlib.dll.so
#14 0x00000000400142c1 in ?? ()
#15 0x00007fffefffebd0 in ?? ()
#16 0x00007ffff4efe988 in System.Threading.Thread:StartInternal (this=...) at <unknown>:693
#17 0x0000000040014273 in ?? ()
#18 0x0000000000000000 in ?? ()
Comment 3 Rodrigo Kumpera 2013-12-06 14:54:00 UTC
Please provide a test case that shows the issue.
Comment 4 Zoltan Varga 2013-12-06 15:06:46 UTC
There is a testcase.
Comment 5 Zoltan Varga 2013-12-10 14:57:21 UTC
This seems to be SGEN only, mono-boehm works.
Comment 6 Zoltan Varga 2013-12-10 15:00:33 UTC
Could you try running with the test with -O=-aot ?
Comment 7 Marian Salaj 2013-12-12 05:57:41 UTC
I have tried -O=-aot but it is still crashing.
This bug could be related to linux version, it is crashing on Debian6 with 3.2.41 kernel, but not on Debian7
Comment 8 Zoltan Varga 2014-01-04 20:04:45 UTC
Fixed an issue in mono master 01f587ef9703abf231fbdde9015ceb4e84bd6e4d, but that only affects AOT code. Are you sure the problem happens even when running with -O=-aot ?
Comment 9 Marian Salaj 2014-01-08 10:55:24 UTC
Sorry my mistake, I tested it again with -O=-aot and it is not crashing, I don't know what I did wrong last time I tested it. The commit also fixed the bug.