I’m using overlapped I/O to read and write to a serial port. When executing the exe from a command prompt, the program will crash (“xxxx.exe has encountered a problem and needs to close…”). The block of code that is using this and is where the application is crashing is called several times before it crashes and works just fine. The weird part is that when I run the executable from VC++ 2010 in debug mode, it does not crash.
This is the block of code where GetOverlappedResult() is crashing…
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() source
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;
}
I have made sure that hComm, the overlapped struct and the pointer to lpNumberOfBytesTransferred are valid.
edit
After adding the debugger environment variable, the program will crash in the debugger… the debugger opens the file tidtable.c and points to the first line of code after the #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
This is the function is being called before it terminates
BOOL Resync( LPBYTE lpbBuffer )
{
DWORD dwBytesRead;
while( Comm.Read( lpbBuffer, 1, &dwBytesRead ) )
if( DDCMP_SOH == *lpbBuffer || DDCMP_ENQ == *lpbBuffer )
return TRUE;
return FALSE;
}
This is what I’ve changed my AsyncSerial::Read() command to be
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;
}
I finally solved my crashes. It appears it was not directly related to the GetOverlappedResult() function. The problem was thread related. I have three threads in my program, the main thread, a thread that reads from the serial port, and a thread that writes to the serial port. I knew the thread that was writing had exited before it got to this point, and instead of assuming the problem was in my read thread, I should have been looking at my main thread.
Thank you for all your help.