【发布时间】:2015-11-02 11:09:29
【问题描述】:
我正在实现一个读取子进程输出的函数。我的程序一般是单线程的,我只使用异步API来实现读取超时(ReadFile()的同步版本不可用)。我创建了一个OVERLAPPED 结构,调用异步ReadFile(),然后使用所需的超时时间调用WaitForSingleObject()。
当读取函数完成时,MSVC 有时会报告:
运行时检查失败 #2 - 围绕变量“rdCount”的堆栈是 损坏。
我尝试了各种调试和修复它的方法。报告的变量只是函数中声明的最后一个变量。从内存来看,函数WaitForSingleObject()有时会出现写三个DWORD,最后一个与rdCount重叠,然后报错。
… cc cc cc cc 00 00 00 00 00 00 00 00 0f 00 00 00 cc cc cc cc …
└ rdCount ┘
否则它只写入这些 DWORD 中的第一个,然后函数正确完成。
… cc cc cc cc 02 01 00 00 cc cc cc cc 00 00 00 00 cc cc cc cc …
└ rdCount ┘
有趣的是,当我添加一些至少 48 字节大小的填充(参见 padding 数组)时,问题就消失了,因为 00 00 00 00 0f 00 00 00 的写入发生在该数组中。
谁能解释一下?是我遗漏了什么还是 WinAPI 有什么问题?
函数主体如下(删除了日志记录和检查)。
HANDLE readFinishEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual-reset event
FALSE, // initial state is nonsignaled
NULL // unnamed
);
QByteArray response;
CHAR buffer[BufferSize];
OVERLAPPED ovl;
CHAR padding[48]; // <----------- ARTIFICIAL PADDING -----------
ZeroMemory(&ovl, sizeof(ovl));
ovl.hEvent = readFinishEvent;
DWORD rdCount;
if(ReadFile(rdPipe, buffer, BufferSize, &rdCount, &ovl) == FALSE)
{
WaitForSingleObject(readFinishEvent, ReadTimeoutMs);
rdCount = ovl.InternalHigh;
}
CloseHandle(readFinishEvent);
response = QByteArray(buffer, (int)rdCount);
return response;
【问题讨论】:
-
您的
OVERLAPPED结构是否恰好超出范围,而ReadFile调用正在进行中?您发布的代码暗示,它没有。这是您使用的确切代码吗?
标签: c++ winapi asynchronous visual-studio-2008