串行COM +多线程导致堆损坏错误 [英] Serial COM + Multi threading gives heap corruption error

查看:115
本文介绍了串行COM +多线程导致堆损坏错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的开发者们,

我在堆上有问题.基本上,我启动了2个线程,一个用于通过串行com端口接收,另一个用于通过串行com端口发送.我声明了一个新的指针,该指针指向我在标头中定义的MsgBlk结构.当我激活sendthread时,程序始终在删除MsgBlk时崩溃.当我删除删除语句,并激活sendthread时,程序在新的MsgBlk delcaration崩溃.阅读了一下,似乎是一个竞争条件或双重删除,但除这里以外,我没有在其他任何地方使用过此msgblk.

仅当我尝试激活发送线程时才会发生崩溃.谁能告诉我发生了什么事?

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??

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;
}

推荐答案

您可能在serial.Read或serial.Write
中没有线程安全代码. stripMsg和packMsg也可能有问题.

我在这里看不到会导致崩溃的任何问题,但这并不意味着还有其他不良情况.

您应该使用事件 [ ^ ]而不是CPU饥饿的循环(在SendThread的顶部).

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).

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;
}


仅供参考-当您请求堆函数时(而不是在发生损坏时),将报告堆损坏问题.您的新"或删除"功能将激活堆检查,然后将报告发生的任何损坏.因此,查看"msgBlk"可能是错误的方向",问题可能确实发生在其他地方,甚至可能在另一个线程中.

您的两个线程都在"myTab"对象中使用函数,如在其他地方建议的那样,可能有助于将它们发布.
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.


这篇关于串行COM +多线程导致堆损坏错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆