我正在使用重叠I / O来读取和写入串行端口。从命令提示符执行exe时,程序将崩溃(“xxxx.exe遇到问题,需要关闭...”)。使用它的代码块是应用程序崩溃的地方,在它崩溃并且工作正常之前会多次调用它。奇怪的是,当我在VC ++ 2010中以调试模式运行可执行文件时,它不会崩溃。
这是GetOverlappedResult()崩溃的代码块...
memset( &ov, 0, sizeof(OVERLAPPED) );
ov.hEvent = CreateEvent( NULL, TRUE, TRUE, NULL );
if( !Comm.Read( lpbBuffer, 1, &dwBytesRead, &ov ) )
if( GetLastError() != ERROR_IO_PENDING )
return FALSE;
if( !Comm.GetOverlappedResult(&ov,&dwBytesRead,TRUE) )
{
printf("Resync: Comm.GetOverlappedResult() failed with error code %u\n", GetLastError() );
return FALSE;
}
Comm.GetOverlappedResult()来源
BOOL SerialAsync::GetOverlappedResult( LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait )
{
printf("made it here\n");
BOOL ret = ::GetOverlappedResult( hComm, lpOverlapped, lpNumberOfBytesTransferred, bWait );
printf("made it here too\n");
return ret;
}
我确保hComm,重叠结构和指向lpNumberOfBytesTransferred的指针是有效的。
修改的
添加调试器环境变量后,程序将在调试器中崩溃...调试器打开文件tidtable.c并指向#ifdef
之后的第一行代码/***
* __set_flsgetvalue - crt wrapper for setting up FlsGetValue pointer in TLS
*
* Purpose:
* This function helps msvcmXX.dll threadstart and threadstartex APIs
* to set FlsGetValue pointer before calling __fls_getvalue.
*
*******************************************************************************/
_CRTIMP PFLS_GETVALUE_FUNCTION __cdecl __set_flsgetvalue()
{
#ifdef _M_IX86
PFLS_GETVALUE_FUNCTION flsGetValue = FLS_GETVALUE;
if (!flsGetValue)
{
flsGetValue = DecodePointer(gpFlsGetValue);
TlsSetValue(__getvalueindex, flsGetValue);
}
return flsGetValue;
#else /* _M_IX86 */
return NULL;
#endif /* _M_IX86 */
}
EDIT2
这是在终止
之前调用的函数BOOL Resync( LPBYTE lpbBuffer )
{
DWORD dwBytesRead;
while( Comm.Read( lpbBuffer, 1, &dwBytesRead ) )
if( DDCMP_SOH == *lpbBuffer || DDCMP_ENQ == *lpbBuffer )
return TRUE;
return FALSE;
}
这就是我将AsyncSerial :: Read()命令更改为
BOOL SerialAsync::ReadOverlapped( LPBYTE lpbBuffer, DWORD dwSize, LPDWORD dwBytesRead, LPOVERLAPPED lpOverlapped )
{
return ReadFile( hComm, lpbBuffer, dwSize, dwBytesRead, lpOverlapped );
}
BOOL SerialAsync::Read( LPBYTE lpbBuffer, DWORD dwSize, LPDWORD dwBytesRead )
{
BOOL bResult = TRUE;
OVERLAPPED ov;
memset( &ov, 0, sizeof(OVERLAPPED) );
ov.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
if( !ReadOverlapped(lpbBuffer,dwSize,dwBytesRead,&ov) )
bResult = GetLastError() == ERROR_IO_PENDING;
if( bResult )
bResult = GetOverlappedResult(&ov,dwBytesRead,TRUE);
CloseHandle( ov.hEvent );
return bResult;
}
答案 0 :(得分:1)
Ahh C ++及其内存问题。你似乎有一堆腐败。它在调试器下工作的原因很可能是由Debug Heap引起的。此症状也称为Heisenbug,这是一种当您仔细观察时会消失的错误。您可以在项目的调试器选项中在流程环境中设置环境变量_NO_DEBUG_HEAP = 1,同时也可以看到您的应用程序在调试器下崩溃。
您提供的代码不包含任何内存分配,因此我无法猜出您的实际问题是什么。
我个人会切换到垃圾收集器清理后的黑暗面(C#,F#)。
答案 1 :(得分:0)
我终于解决了我的崩溃问题。它似乎与GetOverlappedResult()函数没有直接关系。这个问题与线程有关。我的程序中有三个线程,主线程,从串行端口读取的线程,以及写入串行端口的线程。我知道正在编写的线程在它到达这一点之前已经退出了,而不是假设问题出现在我的读取线程中,我应该一直在查看我的主线程。
感谢您的帮助。