c++ - GetOverlappedResult() 在运行时崩溃,但在从 VC++ 2010 进行调试时不会崩溃

标签 c++

<分区>

我正在使用重叠 I/O 来读取和写入串行端口。从命令提示符执行 exe 时,程序会崩溃(“xxxx.exe 遇到问题,需要关闭...”)。使用它的代码块是应用程序崩溃的地方,在它崩溃并且工作正常之前被调用了几次。奇怪的是,当我在 Debug模式下从 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;
}

最佳答案

Ahh C++ 及其内存问题。您似乎有堆损坏。它在调试器下工作的原因很可能是由于 Debug Heap .此症状也称为 Heisenbug这是一个错误,当您仔细观察它时就会消失。您可以在项目的调试器选项中的进程环境中设置环境变量 _NO_DEBUG_HEAP=1,您也会看到您的应用程序在调试器下崩溃。

您提供的代码不包含任何内存分配,因此我无法猜测您的实际问题是什么。

就我个人而言,我会切换到黑暗面(C#、F#),垃圾收集器会在我之后进行清理。

关于c++ - GetOverlappedResult() 在运行时崩溃,但在从 VC++ 2010 进行调试时不会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7999674/

相关文章:

c++ - 必要时扩展Qt接口(interface)

c++ - 所有 system() 调用都存在 C++ 中的安全风险吗?

java - 64位windows 7下Java程序与C程序的stdin/stdout通信

c++ - ubuntu 上的 g++ mudflap

c++ - 在 CPP 中将时间转换为 unix 时间

java - 通过 c、c++ 或 Java 进行 SNMP 访问

c++ - OpenCV CvMat 到 Mat 和指针

以 C 风格编写的 C++ 程序无法使用 C 编译器编译

c++ - 在单元测试文件 : 的 Makefile 中包含 gtest 库

c++ - 保持插入顺序的 C+11 关联容器?