Hey guys, I have a problem with a chess game I'm creating using Windows Forms.

The purpose of this code is that I have a load of panels with picture boxes inside them. When the user moves their cursor over the panel or the picture box, the panel lights up blue. When they move their cursor away, it changes back to its default colour.

Although this code appears to be working correctly (as the panels are changing blue and back again when they are supposed to), if I just run the application and simply move my cursor over each panel (or image), if I do this enough times, the application will crash, giving me the following error:

Problem Event Name: APPCRASH
Application Name: Chess.exe
Application Version: 0.0.0.0
Application Timestamp: 4d3b8d5d
Fault Module Name: clr.dll
Fault Module Version: 4.0.30319.1
Fault Module Timestamp: 4ba1d9ef
Exception Code: c0000005
Exception Offset: 000b9b41
OS Version: 6.1.7600.2.0.0.256.48
Locale ID: 2057
Additional Information 1: 9b33
Additional Information 2: 9b337a60891deea949636df6511bca4e
Additional Information 3: 44f4
Additional Information 4: 44f48f929ff30f1f00f6b46040669596

and this error message on the Visual C++ debugger:

Managed Debugging Assistant 'FatalExecutionEngineError' has detected a problem in 'C:\Users\David\Projects\C++ Projects\Chess\Development Builds\Current Build\Debug\Chess.exe'.
Additional Information: The runtime has encountered a fatal error. The address of the error was at 0x6e689b41, on thread 0x6e4. 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.

So my question is, what is causing these errors? Here's my code:

this->SquareID[i]->MouseEnter += gcnew System::EventHandler(this,&Form1::Square_MouseEnter);
this->SquareImageID[i]->MouseEnter += gcnew System::EventHandler(this,&Form1::Square_MouseEnter);
this->SquareID[i]->MouseLeave += gcnew System::EventHandler(this,&Form1::Square_MouseLeave);
this->SquareImageID[i]->MouseLeave += gcnew System::EventHandler(this,&Form1::Square_MouseLeave);
private: System::Void Square_MouseEnter(System::Object^ sender, System:: EventArgs^ e)
{
			if(BoardFrozen == 1) return;
			int a = -1;
			for(int i=0;i<MAX_SQUARES;i++)
			{
				if(sender == SquareID[i] || sender == SquareImageID[i])
				{
					a = i;
					break;
				}
			}
			if(!IsValidSquareID(a)) return;
			if(PreviousSquareSelected == -1)
			{
				if(!IsSquareOccupiedByAllyOfPlayer(a)) return;
			}
			if(PreviousSquareSelected > -1)
			{
				if(a == PreviousSquareSelected) return;
				if(!IsValidMove(PreviousSquareSelected,a))
				{
					this->SquareID[a]->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(230)), static_cast<System::Int32>(static_cast<System::Byte>(0)), 
					static_cast<System::Int32>(static_cast<System::Byte>(0)));
					return;
				}
				else
				{
					this->SquareID[a]->BackColor = System::Drawing::Color::LimeGreen;
					return;
				}
			}
			this->SquareID[a]->BackColor = System::Drawing::Color::DodgerBlue;
			return;
}
private: System::Void Square_MouseLeave(System::Object^ sender, System:: EventArgs^ e)
		 {
			if(BoardFrozen == 1) return;
			int a = -1;
			for(int i=0;i<MAX_SQUARES;i++)
			{
				if(sender == SquareID[i] || sender == SquareImageID[i])
				{
					a = i;
					break;
				}
			}
			if(!IsValidSquareID(a)) return;
			if(a == PreviousSquareSelected) return;
			SetSquareToDefaultColour(a);
			return;
		 }

Thank you very much in advance for any assistance that anyone provides.

I'm not sure, and I'm not so familiar with C++/CLI (which is not the same language as C++).

But what if you reach the line below, while a is still equal to -1. I think there is a slight chance that it does, so you might want to do a little check before that a is a valid index.

this->SquareID[a]->BackColor = System::Drawing::Color::DodgerBlue;

I'm not sure, and I'm not so familiar with C++/CLI (which is not the same language as C++).

But what if you reach the line below, while a is still equal to -1. I think there is a slight chance that it does, so you might want to do a little check before that a is a valid index.

this->SquareID[a]->BackColor = System::Drawing::Color::DodgerBlue;

Thanks, I just tried this and it didn't help.

if(!IsValidSquareID(a)) return; should be preventing this from happening anyway as that function determines whether or not a is below 0 or above 63.

Edited 5 Years Ago by David_Omid: n/a

Little update, managed to confirm that the bug exists in the MouseLeave portion of code. Will investigate further.

I don't do anything with GUIs or CLI, but I noticed you are using the compound addition operator to attach the EventHandlers. Maybe I'm missing something, but shouldn't that be the regular assignment operator, not a compound operator?

Just did some more tests, it appears to only crash when the colour of the panels is changed twice in close succession.

This is quite a problem. Not quite sure what to do about this...

Uhmm.. Maybe the problem is that both handlers that you have get executed at the same time (since they come in very quick succession. This could happen if the GUI handles events with multiple threads of execution. It registers an event for Mouse Enter, then starts to execute it, and during the execution, a Mouse Leave event is registered and starts executing before the other has finished. That possibly could cause a crash (but either your handler's execution must be slow or the GUI poorly responsive for that situation to happen).

Maybe you should add a critical section (or mutex) to prevent the execution of both handlers at the same time. By locking the same mutex or critical section in both handlers, you will force the second one to occur to wait for the first one to be finished, i.e. preventing them from executing simultaneously.

I don't do anything with GUIs or CLI, but I noticed you are using the compound addition operator to attach the EventHandlers. Maybe I'm missing something, but shouldn't that be the regular assignment operator, not a compound operator?

The compound operator is used there because it is possible to hook up more than one event handler to a single event.

Comments
I understand now. Thanks.

Uhmm.. Maybe the problem is that both handlers that you have get executed at the same time (since they come in very quick succession. This could happen if the GUI handles events with multiple threads of execution. It registers an event for Mouse Enter, then starts to execute it, and during the execution, a Mouse Leave event is registered and starts executing before the other has finished. That possibly could cause a crash (but either your handler's execution must be slow or the GUI poorly responsive for that situation to happen).

Maybe you should add a critical section (or mutex) to prevent the execution of both handlers at the same time. By locking the same mutex or critical section in both handlers, you will force the second one to occur to wait for the first one to be finished, i.e. preventing them from executing simultaneously.

Thanks, I'll see if this helps later.

This article has been dead for over six months. Start a new discussion instead.