我正在实现一个读取子进程输出的函数。我的程序通常是单线程的,我只使用异步API来实现读取超时(attr_reader :custom_attribute
def custom_attribute=(value)
# some validation code here ...
@custom_attribute = value
end
的同步版本不可用)。我创建了一个ReadFile()
结构,调用异步OVERLAPPED
,然后ReadFile()
调用所需的超时。
当读取功能完成时,MSVC有时会报告:
运行时检查失败#2 - 堆栈变量'rdCount'是 损坏。
我尝试了各种调试和修复方法。报告的变量只是函数中声明的最后一个变量。根据内存视图,函数WaitForSingleObject()
有时会出现写三个DWORD,其中最后一个与WaitForSingleObject()
重叠,然后报告损坏。
rdCount
否则它只写入这些DWORD中的第一个,然后函数正确完成。
… cc cc cc cc 00 00 00 00 00 00 00 00 0f 00 00 00 cc cc cc cc …
└ rdCount ┘
有趣的是,当我添加一些大小至少为48字节的填充(请参阅… cc cc cc cc 02 01 00 00 cc cc cc cc 00 00 00 00 cc cc cc cc …
└ rdCount ┘
数组)时,问题就会消失,因为padding
的写入发生在该数组中。
任何人都可以解释一下吗?我错过了什么或WinAPI有什么问题吗?
函数体跟随(记录和检查已删除)。
00 00 00 00 0f 00 00 00
答案 0 :(得分:7)
WaitForSingleObject(readFinishEvent, ReadTimeoutMs);
Yikes,这是一个非常讨厌的错误,你很幸运能得到诊断。永远不要忽略winapi函数的返回值。当它返回WAIT_TIMEOUT时,这会严重失败。如果没有正确处理,则忘记取消I / O操作。
随后的灾难在实际完成时发生,稍后,驱动程序将垃圾喷射到曾经位于buffer
和ovl
的堆栈中。当您继续调用此功能时,您将获得诊断。但总的来说,函数的任何局部变量都可能被破坏。非常难以诊断,购买微软一支雪茄来实施/ RTC
当您获得除WAIT_OBJECT_0之外的任何其他返回值时,必须调用CancelIo()。