FatalExecutionEngineError detected in C # code after calling TerminateThread in C ++ code

If I call TerminateThread from C ++ code, then later I get FatalExecutionEngineError MDA later. This error occurs when I perform various operations on strings (i.e. Concat). The code below simply shows how to reproduce it.

Why is this happening? How can I fix it and use TerminateThread?

thanks

Error:

FatalExecutionEngineError was detected Message: The runtime has encountered a fatal error. The address of the error was at 0x7880bb35, on thread 0x18f0. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack. 

C ++ Code:
Module.cpp:

 #include "ThreadModule.h" using namespace ThreadModule; DWORD WINAPI workThread(LPVOID lpParam) { while(1) { System::Threading::Thread::Sleep(5); printf("."); } return 0; } bool Module::StartThread() { handle = CreateThread( NULL, 0, workThread, NULL, 0, &threadIdInput); return true; } bool Module::StopThread() { TerminateThread(handle, 0); handle = NULL; return true; } 

C # code:

 static void Main(string[] args) { Module module = new Module(); module.StartThread(); string s = ""; for (int i = 0; i < 10000; i++) { s += i.ToString(); } module.StopThread(); s = ""; for (int i = 0; i < 10000; i++) { s += i.ToString(); //After ~250 iteration get exception } Console.WriteLine("Completed!!"); } 
+4
source share
1 answer
  System::Threading::Thread::Sleep(5); 

In a running thread, managed code is run, not native C ++ code. Obviously, you compiled this with the / clr option so you can write C ++ / CLI code. This is a problem the CLR knows about this thread. Necessarily, this is necessary to look at the thread stack when starting the garbage collector to look for links to managed objects.

What kills the thread with TerminateThread () is a problem, more than it is, it is a dangerous winapi function that does not clean up. The CLR crashes when it scans the stack of this dead thread.

The CLR can perform safe thread interrupts with Thread :: Abort (). This is still not recommended, but at least you won’t force your program to go bad. Note that Abort () will not work when a thread runs its own code. Of course, it is best to completely abandon the idea that stopping flows is a good idea.

The obvious place to ask the thread to stop nicely is the while (1) statement.

+4
source

All Articles