Bug 11877 - Mono crashes when a large number of AppDomains is Created but not Unloaded
Summary: Mono crashes when a large number of AppDomains is Created but not Unloaded
Alias: None
Product: Runtime
Classification: Mono
Component: General ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
Depends on:
Reported: 2013-04-21 19:30 UTC by Alexandre Faria
Modified: 2013-05-17 13:09 UTC (History)
4 users (show)

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:

Description Alexandre Faria 2013-04-21 19:30:07 UTC
Mono crashes when a large number of AppDomains (3000+ on Ubuntu git, 1200+ on windows mono 3.0.9) is created but not unloaded.

.Net also crashes on 8600+ with an out of memory.

Obviously this use case has nothing to do with the real use case, but its a simplification of a situation that takes several hours to pop up.

Previously I thought that this one and many others were just redundant variations of one that was just fixed, as this one is still broken, I hope it helps.

This test case reproduces the problem:

using System;

public class Example
  public static void Main()
    for(int i=0; i<10000; i++)
      System.Console.WriteLine("\n\nIteration " + i);

The exception:

* Assertion at mini.c:3869, condition `code' not met


  at <unknown> <0xffffffff>
  at System.IO.StreamReader..ctor (string) <0x00013>
  at (wrapper remoting-invoke-with-check) System.IO.StreamReader..ctor (string) <0xffffffff>
  at System.Security.Cryptography.CryptoConfig.LoadConfig (string,System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) <0x00057>
  at System.Security.Cryptography.CryptoConfig.Initialize () <0x01853>
  at System.Security.Cryptography.CryptoConfig.CreateFromName (string,object[]) <0x0007b>
  at System.Security.Cryptography.CryptoConfig.CreateFromName (string) <0x0000f>
  at System.Security.Cryptography.RandomNumberGenerator.Create (string) <0x0000f>
  at System.Security.Cryptography.RandomNumberGenerator.Create () <0x00013>
  at System.Guid.NewGuid () <0x00077>
  at System.Runtime.Remoting.RemotingServices.NewUri () <0x0007f>
  at System.Runtime.Remoting.RemotingServices.Marshal (System.MarshalByRefObject,string,System.Type) <0x00243>
  at System.AppDomain.GetMarshalledDomainObjRef () <0x0001f>
  at (wrapper runtime-invoke) <Module>.runtime_invoke_object__this__ (object,intptr,intptr,intptr) <0xffffffff>
  at <unknown> <0xffffffff>
  at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) <0xffffffff>
  at System.AppDomain.InvokeInDomain (System.AppDomain,System.Reflection.MethodInfo,object,object[]) <0x00093>
  at System.Runtime.Remoting.RemotingServices.GetDomainProxy (System.AppDomain) <0x00063>
  at System.AppDomain.CreateDomain (string,System.Security.Policy.Evidence,System.AppDomainSetup) <0x001df>
  at System.AppDomain.CreateDomain (string) <0x00013>
  at Example.Main () <0x00053>
  at (wrapper runtime-invoke) object.runtime_invoke_void (object,intptr,intptr,intptr) <0xffffffff>

Native stacktrace:

	mono() [0x4a9cd1]
	/lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0) [0x7ff5a88c8cb0]
	/lib/x86_64-linux-gnu/libc.so.6(gsignal+0x35) [0x7ff5a8530425]
	/lib/x86_64-linux-gnu/libc.so.6(abort+0x17b) [0x7ff5a8533b8b]
	mono() [0x61001d]
	mono() [0x610156]
	mono() [0x4213bd]
	mono() [0x4231f2]
	mono() [0x423b52]
	mono() [0x4245fd]
	mono() [0x4abb7d]

Debug info from gdb:

Could not attach to process.  If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user.  For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operação não permitida.
No threads.

Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
Comment 1 Zoltan Varga 2013-04-22 13:29:39 UTC
The process is probably running out of memory.
Comment 2 Alexandre Faria 2013-04-22 16:41:24 UTC
Well in linux its taking about 3GB of RAM, I had processes well over that, at least around 6GB, so I'm guessing it shouldn't be it, perhaps it might be on windows, not sure there, as I'm just using it to understand if bugs are linux specific.

I have mono compiled with --with-large-heap=yes

I believe the test case is quite stupid as I don't envision a real use case in any way similar.

But bugs like this are quite hard to isolate with the least amount of code and execution time and sometimes testing for extreme situations does help to flush them out.
Comment 3 Rodrigo Kumpera 2013-05-17 11:57:06 UTC
Are you using a 32 or 64 bits mono. --with-large-heaps have nothing to do with this problem, it has to do with the size of the managed heap.

The solution is pretty simple, release your appdomains once you're done with them.
Comment 4 Alexandre Faria 2013-05-17 13:09:35 UTC
I'm using a 64 bits mono.

I know that if I release them, it works, that's not the problem.
And I obviously do that in my code.

The problem is that if it released an error like out of memory like .net does it would be a lot easier for me to understand if other errors that I'm getting, that are much harder to isolate, are the same or not.
That beyond the point of testing the limits.

To make it clear, my point is: if mono could terminate in a more understandable way it would be easier to understand what when wrong and differentiate between different exceptions.

I wouldn't mind if for performance reasons it would have to be enabled in a compile flag.