none
System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly multithread deadlock RRS feed

  • Question

  • Hello,

    I encountered an issue related to multiple calls to the DefineDynamicAssembly method from parallel threads. It cannot be reproduced reliably and occurs rarely. No exception is thrown. Application execution locks when multiple threads call this method at the same time.

    Here is a console app code that can reproduce it sometimes. Eventually, it will crash with OutOfMemory.

    public partial class App : Application {
            int i = 0;
            protected override void OnStartup(StartupEventArgs e) {
                base.OnStartup(e);
    
                Test();
            }
            void Test() {
                while (true) {
                    var t1 = new Thread(TryGetBuilder);
                    var t2 = new Thread(TryGetBuilder);
                    var t3 = new Thread(TryGetBuilder);
    
                    t1.Start();
                    t2.Start();
                    t3.Start();
                }
            }
            void TryGetBuilder() {
                var builder = ModuleBuilderSource.GetModuleBuilder();
                Console.WriteLine($"Success {i} - {builder.FullName}");
                i++;
            }
        }
    
        public class ModuleBuilderSource {
            public static AssemblyBuilder GetModuleBuilder() {
                return AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run);
            }
        }

    Do you have any advice for this scenario?

    Tuesday, October 15, 2019 11:56 AM

All replies

  • Some callstacks related to the issue:

    ntdll.dll!_ZwWaitForMultipleObjects@20()	Unknown
     	KERNELBASE.dll!_WaitForMultipleObjectsEx@20()	Unknown
     	kernel32.dll!_WaitForMultipleObjectsExImplementation@20()	Unknown
     	[Managed to Native Transition]	
    >	mscorlib.dll!System.Reflection.Emit.AssemblyBuilder.InternalDefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, string dir, System.Security.Policy.Evidence evidence, System.Security.PermissionSet requiredPermissions, System.Security.PermissionSet optionalPermissions, System.Security.PermissionSet refusedPermissions, ref System.Threading.StackCrawlMark stackMark, System.Collections.Generic.IEnumerable<System.Reflection.Emit.CustomAttributeBuilder> unsafeAssemblyAttributes, System.Security.SecurityContextSource securityContextSource) Line 581	C#
     	mscorlib.dll!System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access) Line 504	C#
    ntdll.dll!_ZwWaitForMultipleObjects@20()	Unknown
     	KERNELBASE.dll!_WaitForMultipleObjectsEx@20()	Unknown
     	kernel32.dll!_WaitForMultipleObjectsExImplementation@20()	Unknown
     	[Managed to Native Transition]	
     	mscorlib.dll!System.Reflection.Emit.AssemblyBuilder.InternalDefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, string dir, System.Security.Policy.Evidence evidence, System.Security.PermissionSet requiredPermissions, System.Security.PermissionSet optionalPermissions, System.Security.PermissionSet refusedPermissions, ref System.Threading.StackCrawlMark stackMark, System.Collections.Generic.IEnumerable<System.Reflection.Emit.CustomAttributeBuilder> unsafeAssemblyAttributes, System.Security.SecurityContextSource securityContextSource) Line 581	C#
     	mscorlib.dll!System.Reflection.Emit.DynamicMethod.GetDynamicMethodsModule() Line 326	C#
     	mscorlib.dll!System.Reflection.Emit.DynamicMethod.Init(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] signature, System.Type owner, System.Reflection.Module m, bool skipVisibility, bool transparentMethod, ref System.Threading.StackCrawlMark stackMark) Line 380	C#
     	mscorlib.dll!System.Reflection.Emit.DynamicMethod.DynamicMethod(string name, System.Type returnType, System.Type[] parameterTypes, bool restrictedSkipVisibility) Line 116	C#
    ntdll.dll!_NtWaitForSingleObject@12()	Unknown
     	ntdll.dll!_RtlpWaitOnCriticalSection@8()	Unknown
     	ntdll.dll!_RtlEnterCriticalSection@4()	Unknown
     	clrjit.dll!Compiler::impResolveToken(const unsigned char * addr, CORINFO_RESOLVED_TOKEN * pResolvedToken, CorInfoTokenKind kind) Line 282	C++
     	clrjit.dll!Compiler::impImportBlockCode(BasicBlock * block) Line 10496	C++
     	clrjit.dll!Compiler::impImportBlock(BasicBlock * block) Line 13238	C++
     	clrjit.dll!Compiler::impImport(BasicBlock * method) Line 14187	C++
     	[Inline Frame] clrjit.dll!Compiler::fgImport() Line 6060	C++
     	clrjit.dll!Compiler::compCompile(void * * methodCodePtr, unsigned long * methodCodeSize, unsigned int compileFlags) Line 2491	C++
     	clrjit.dll!Compiler::compCompileHelper(CORINFO_MODULE_STRUCT_ * classPtr, ICorJitInfo * compHnd, CORINFO_METHOD_INFO * methodInfo, void * * methodCodePtr, unsigned long * methodCodeSize, unsigned int compileFlags, CorInfoInstantiationVerification instVerInfo) Line 3615	C++
     	clrjit.dll!Compiler::compCompile(CORINFO_METHOD_STRUCT_ * methodHnd, CORINFO_MODULE_STRUCT_ * classPtr, ICorJitInfo * compHnd, CORINFO_METHOD_INFO * methodInfo, void * * methodCodePtr, unsigned long * methodCodeSize, unsigned int compileFlags) Line 3092	C++
     	clrjit.dll!jitNativeCode(CORINFO_METHOD_STRUCT_ * methodHnd, CORINFO_MODULE_STRUCT_ * classPtr, ICorJitInfo * compHnd, CORINFO_METHOD_INFO * methodInfo, void * * methodCodePtr, unsigned long * methodCodeSize, unsigned int compileFlags, void * inlineInfoPtr) Line 4063	C++
     	clrjit.dll!CILJit::compileMethod(ICorJitInfo * compHnd, CORINFO_METHOD_INFO * methodInfo, unsigned int flags, unsigned char * * entryAddress, unsigned long * nativeSizeOfCode) Line 180	C++
     	[Managed to Native Transition]	
     	mscorlib.dll!System.AppDomain.OnAssemblyLoadEvent(System.Reflection.RuntimeAssembly LoadedAssembly) Line 3116	C#
     	[Native to Managed Transition]	
     	clrjit.dll!Compiler::impCheckCanInline(GenTree * call, CORINFO_METHOD_STRUCT_ * fncHandle, unsigned int methAttr, CORINFO_METHOD_STRUCT_ * exactContextHnd, InlineCandidateInfo * * ppInlineCandidateInfo) Line 14862	C++
     	[Managed to Native Transition]	
     	mscorlib.dll!System.AppDomain.OnAssemblyLoadEvent(System.Reflection.RuntimeAssembly LoadedAssembly) Line 3116	C#
     	[Native to Managed Transition]	
     	mscorlib.ni.dll!71e3018d()	Unknown
     	[Managed to Native Transition]	
     	mscorlib.dll!System.Reflection.Emit.AssemblyBuilder.AssemblyBuilder(System.AppDomain domain, System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, string dir, System.Security.Policy.Evidence evidence, System.Security.PermissionSet requiredPermissions, System.Security.PermissionSet optionalPermissions, System.Security.PermissionSet refusedPermissions, ref System.Threading.StackCrawlMark stackMark, System.Collections.Generic.IEnumerable<System.Reflection.Emit.CustomAttributeBuilder> unsafeAssemblyAttributes, System.Security.SecurityContextSource securityContextSource) Line 424	C#
     	mscorlib.dll!System.Reflection.Emit.AssemblyBuilder.InternalDefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, string dir, System.Security.Policy.Evidence evidence, System.Security.PermissionSet requiredPermissions, System.Security.PermissionSet optionalPermissions, System.Security.PermissionSet refusedPermissions, ref System.Threading.StackCrawlMark stackMark, System.Collections.Generic.IEnumerable<System.Reflection.Emit.CustomAttributeBuilder> unsafeAssemblyAttributes, System.Security.SecurityContextSource securityContextSource) Line 569	C#
     	mscorlib.dll!System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access) Line 504	C#

    • Edited by Noxis_ Tuesday, October 15, 2019 12:29 PM
    Tuesday, October 15, 2019 12:28 PM
  • Hi Noxis_,

    Thank you for posting here.

    According to your question, I create a console application to make a test, and it works well.

    Then I make a test in xamarin.forms, I still get no exception, and the application doesn't crash with OutOfMemory.

    Could you provide more information to help us to reproduce your problem?

    Besides, if your question is more related xamarin, I suggest you post the question in xamarin forums for better help.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, October 16, 2019 8:38 AM
    Moderator
  • Hello Xingyu,

    Thank you for your reply. This issue is not related to Xamarin at any point. The actual environment that I work with is C#/WPF desktop applications. Also, the OutOfMemory exception is not related to the main issue. It is kind of strange that it does not occur on your side as the application has a while(true) loop but it does not matter much.

    As for the issue, as I mentioned, it is very unreliable. I was able to reproduce it only two times in a couple of weeks. Maybe the call stacks make some help there?

    Thursday, October 17, 2019 4:00 PM