[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