[Mono-dev] ExecutionEngineException: Couldn't create thread

Brian Crowell mono-devel at fluggo.com
Fri Jun 23 11:52:54 EDT 2006


I've got the following sequence staring at me:

====================

** (/opt/ProgramName.Withheld.exe:2670): WARNING **: CreateThread: error 
creating thread handle

Unhandled Exception: System.ExecutionEngineException: Couldn't create thread
in <0x00000> <unknown method>
in (wrapper delegate-begin-invoke) System.MulticastDelegate:begin_invoke_IAsyncR
esult_object_AsyncCallback_object (object,System.AsyncCallback,object)
in <0x00015> System.Threading.ThreadPool:QueueUserWorkItem (System.Threading.Wai
tCallback callback, System.Object state)
in <0x00006> System.Timers.StartTimer ()
in (wrapper delegate-invoke) System.MulticastDelegate:invoke_void ()

** (/opt/ProgramName.Withheld.exe:2670): WARNING **: _wapi_handle_unref: 
Attempting to unref unused handle 0x20b3a8

** (/opt/ProgramName.Withheld.exe:2670): WARNING **: _wapi_handle_unref: 
Attempting to unref unused handle 0x20b2d0

** (/opt/ProgramName.Withheld.exe:2670): WARNING **: _wapi_handle_unref: 
Attempting to unref unused handle 0x20b120

** (/opt/ProgramName.Withheld.exe:2670): WARNING **: _wapi_handle_unref: 
Attempting to unref unused handle 0x20b1f8

====================

...and there the program has hung.

I'm going to attempt to reproduce the error with a test case, but in the 
meantime, here's the highlights:

====================
class MainClass {
     public static int Main( string[] args ) {
         // Check args, return one if there's a problem

        _timer = new System.Timers.Timer( 10.0 );
        _timer.BeginInit();
        _timer.AutoReset = false;
        _timer.Elapsed += new System.Timers.ElapsedEventHandler( 
HandleTimerElapsed );
        _timer.EndInit();
        _timer.Start();

	// Do not allow the program to end
	Thread.CurrentThread.Suspend();

	return 0;
     }

     private static void HandleTimerElapsed( object sender, 
System.Timers.ElapsedEventArgs e ) {
         try {
             // Set the interval to something substantially higher
             // (on the order of several minutes)
             _timer.Interval = someLongerInterval;
             _timer.Start();

             DoSomethingThatMayOrMayNotBeLongerThanTheInterval();
         }
         catch( ThreadAbortException ) {
             throw;
         }
         catch( Exception ex ) {
             // Default: check every minute if there's an error
             _timer.Interval = 60000.0;
             _timer.Start();

             Console.Error.WriteLine( ex );
         }
     }
}
====================

In the instance that produced the above error, 
DoSomethingThatMayOrMayNotBeLongerThanTheInterval() was always shorter than the 
interval. (unless, I suppose, something in that call hung, but then the 
thread-pool should just be starved, and shouldn't throw a wrench)

Other possible sources of threads:

* The program uses remoting heavily
* The program does a lot of work in a separate AppDomain (but does not 
explicitly create threads, nor uses asynchronous invokes or the thread pool)
* The program often calls System.Diagnostics.Process.Start() followed by 
process.WaitForExit()

Also, while the program has changed slightly since I last ran it on 1.1.13.4, 
that version did not exhibit this behavior. I am running it on my domain-patched 
1.1.13.8 (which funnels all cross-domain calls through the CrossAppDomainChannel).

--Brian






More information about the Mono-devel-list mailing list