Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Dear fellow devs,

I am having some problem with the heap. Basically I spin up 2 threads one for receiving and one for sending via the serial com port. I declare a new pointer to a struct MsgBlk I defined in the header. the program keeps crashing at the delete MsgBlk when i activate the sendthread. When i remove the delete statement, and when the sendthread is activated, the program crashes at the new MsgBlk delcaration. Read up and it seems like a race condition or double deletion, but i have not used this msgblk anywhere else except here.

the crash only happens when i try to activate the send thread. can anyone tell me whats happening??

C++
unsigned long ReceiveThread(CMyTabs* myTab)
{
    while(true)
    {
    	if(!initialisePort)
	{
		//LONG error = serial.Open(_T("\\\\.\\\\COM5"));

		// Setup the serial port (9600,N81) 
		initialisePort = true;
	}
		
	DWORD dwBytesRead = 0;
	byte abBuffer[256];
	bool crcCheck = false;
	bool msgCheck = false;
	// declare msgBlk
	MsgBlk *msgBlk = new MsgBlk();
	do
	{
		crcCheck = msgBlk->fValidCRC;
		msgCheck = msgBlk->fValid;
		// do polling for data
		serial.Read(abBuffer, 256, &dwBytesRead, 0, INFINITE);
		// if bytes more than 0
		if(dwBytesRead > 0)
		{
			myTab->stripMsg(abBuffer, sizeof(abBuffer), msgBlk);
		}
		Sleep(50);
	}while(!msgCheck && !crcCheck);
		
	char szTimestamp[128];
	SYSTEMTIME st;
	//GetSystemTime(&st);
	GetLocalTime(&st);
	sprintf_s(szTimestamp, 128, "%02d:%02d:%02d:%03d", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

	byte bytetobesent[256];
	for(int k=0; k<256; ++k)
	{
		bytetobesent[k] = msgBlk->msg[k];
	}

	PostMessage(myTab->GetSafeHwnd(), WM_MSG_RECV, (WPARAM)bytetobesent, (LPARAM)szTimestamp);
	delete msgBlk;
}
return 0;
}


unsigned long SendThread(CMyTabs* myTab)
{
	while(true)
	{
		while(!sendMsgFlag)
		{
			Sleep(0);
		}
		++sendCounter;
		sendMsgFlag = false;
		// send message 41
		DWORD dwBytesWritten=0;
		int in_len;
		int	out_len;
		int oplen;
		byte inbuf[5];
		byte outbuf[512];

		inbuf[0] = 0x06;	
		inbuf[1] = 0x33;	
		inbuf[2] = sendCounter;	
		inbuf[3] = (sendCounter >> 8);	
		inbuf[4] = 112;		

		out_len = in_len = 5;

		oplen = myTab->packMsg(inbuf, in_len, outbuf, out_len);
		
		long Lerror = serial.Write(outbuf, oplen);
		
		if(Lerror != ERROR_SUCCESS)
		{
			AfxMessageBox(_T("Unable to write to COM Port!"));
		}
	}
	return 0;
}
Posted
Updated 31-Oct-11 12:38pm
v7
Comments
Mehdi Gholam 31-Oct-11 0:49am    
Using a serial port is in the name, it should be done sequentially and in one thread, try sending and recieving in one thread.

You may not have thread-safe code in serial.Read or serial.Write
stripMsg and packMsg may also have issues.

I don't see any issues which would be causing crashes here, but that doesn't mean there are some other bad things.

You should use events[^] instead of CPU hungry loops (at the top of SendThread).

C++
unsigned long ReceiveThread(CMyTabs* myTab)
{
    while(true)
    {
    	if(!initialisePort)
	{
		//LONG error = serial.Open(_T("\\\\.\\\\COM5"));

		// Setup the serial port (9600,N81) 
		initialisePort = true;
	}
		
	DWORD dwBytesRead = 0;
	byte abBuffer[256];
	bool crcCheck = false;
	bool msgCheck = false;
	// declare msgBlk
	MsgBlk *msgBlk = new MsgBlk();
	do
	{
		crcCheck = msgBlk->fValidCRC;
		msgCheck = msgBlk->fValid;
		// do polling for data
		serial.Read(abBuffer, 256, &dwBytesRead, 0, INFINITE);
		// if bytes more than 0
		if(dwBytesRead > 0)
		{
			myTab->stripMsg(abBuffer, sizeof(abBuffer), msgBlk);
		}
		Sleep(50); //Sleep is typically bad style. You can set time-outs for reading files.
	}while(!msgCheck && !crcCheck);
		
	char szTimestamp[128];
	SYSTEMTIME st;
	//GetSystemTime(&st);
	GetLocalTime(&st);
	sprintf_s(szTimestamp, 128, "%02d:%02d:%02d:%03d", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
 
	byte bytetobesent[256];
	//What is wrong with memcpy?
	/*for(int k=0; k<256; ++k)
	{
		bytetobesent[k] = msgBlk->msg[k];
	}*/
	memcpy(bytetobesent, msgBlk->msg, sizeof(bytetobesent));
	//This is bad. What happens to bytetobesent here?
	//It is destroyed when the function exits, which is possibly before the handler for WM_MSG_RECV is invoked.
	//You will need to create a global buffer or allocate memory on the heap with malloc/new
	//Alternativley you can use SendMessage, which will invoke and complete WM_MSG_RECV before returning back here.
	PostMessage(myTab->GetSafeHwnd(), WM_MSG_RECV, (WPARAM)bytetobesent, (LPARAM)szTimestamp);
	delete msgBlk;
    }
    return 0;
}
 

unsigned long SendThread(CMyTabs* myTab)
{
	while(true)
	{
		//This is really bad. Use an Event. See notes above.
		/*while(!sendMsgFlag)
		{
			Sleep(0);
		}*/
		WaitForSingleObject(hMyEvent, INFINITE);
		++sendCounter;
		sendMsgFlag = false;
		// send message 41
		DWORD dwBytesWritten=0;
		int in_len;
		int	out_len;
		int oplen;
		byte inbuf[5];
		byte outbuf[512];
 
		//AfxMessageBox(_T("Testing WIA req"));
		inbuf[0] = 0x06;	
		inbuf[1] = 0x33;	
		inbuf[2] = sendCounter;	
		inbuf[3] = (sendCounter >> 8);	
		inbuf[4] = 112;		
 
		out_len = in_len = 5;
 
		oplen = myTab->packMsg(inbuf, in_len, outbuf, out_len);
		
		long Lerror = serial.Write(outbuf, oplen);
		
		if(Lerror != ERROR_SUCCESS)
		{
			AfxMessageBox(_T("Unable to write to COM Port!"));
		}
	}
	return 0;
}
 
Share this answer
 
Comments
Andrew Brock 31-Oct-11 2:48am    
Could you please update your original question to include the class definition of serial and more importantly MsgBlk and CMyTabs::stripMsg.
I suspect you are writing to memory outside the allocated block for msgBlk, which is causing the heap corruption.
FYI - heap corruption problems are reported when you request heap functions and not necessarily when the corruption occurs. Your "new" or "delete" functions activate the heap checking and any corruption that occurred will then be reported. So, looking at "msgBlk" may be a "misdirection", the problem may really occur elsewhere, maybe even in another thread.

Both your threads use functions in a "myTab" object, it might help to post them as has been suggested elsewhere.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900