ReadFile!= 0,lpNumberOfBytesRead = 0,但偏移量不在文件末尾

时间:2018-09-07 09:51:26

标签: windows winapi

我们正努力了解以下错误的来源:

我们有一个“ ReadFile”(同步)调用,它返回一个非零值(成功),但将lpNumberOfBytesRead参数填充为0。理论上,这表明偏移量在文件外部,但是,实际上,这是不正确的。 GetLastError返回ERROR_SUCCESS(0)。

有问题的文件全部在共享的网络驱动器上(Windows Server 2016 + DFS,Windows 8-10客户端,SMBv3)。这些文件以共享模式使用。文件内锁定(lockFileEx)用于处理并发文件访问(我们只是在任何读/写之前锁定文件的第一个字节)。

所使用的句柄并不新鲜:它不是在函数中本地创建的,而是从应用程序范围的“文件句柄缓存管理器”中检索的。这意味着它可能是在某些时候创建(未使用)的。但是,我们所做的一切都表明该句柄在调用时是有效的:GetLastError返回0,GetFileInformationByHandle返回“ true”和一个有效的结构。

将错误记录到与有问题的文件位于同一文件服务器上的文件中。

我们已经围绕此问题进行了许多日志记录和测试。这是我们收集到的其他事实:

  • 大多数(但不是全部)有问题的读取发生在文件的最后:我们正在读取最后一条记录。但是,读取仍在文件GetlastError中,不会返回ERROR_HANDLE_EOF。如果程序重新启动,则具有相同参数的相同读取将起作用。
  • 问题不是暂时的:即使我们无限期地循环程序,重复调用也会产生相同的结果。但是,重新启动程序并不会自动导致立即再次引发该问题。
  • 我们可以确定文件内部是否存在偏移量:我们会在发生故障后检查文件的实际指针位置,并将其与操作系统报告的预期值以及文件大小进行比较:所有匹配项均重试多次。
  • 该问题仅是随机出现的:程序没有按预期方式正常工作且程序失败的真实模式。每天在我们的办公室中发生2-4次(约20人)。
  • 此问题不仅发生在我们的网络中。尽管我们对这些情况所涉及的操作系统没有清晰的了解,但我们已经在多个位置看到了症状和日志条目。

我们刚刚部署了该程序的新版本,它将在失败的情况下尝试重新打开文件,但这是一种解决方法,而不是解决方法:我们需要了解此处发生的情况,我必须承认我发现了对此没有合理的解释

任何有关导致此错误的原因或可以采取其他措施找出错误的建议都将受到欢迎。

编辑2 (鉴于此,我删除了代码:新证据对问题进行了更好的解释)

当问题发生时,我们设法获得了procmon跟踪,并且得到了以下事件序列,我们无法解释:

ProcMon captured lines

文本版本:

"Time of Day","Process Name","PID","Operation","Path","Result","Detail","Command Line"
"9:43:24.8243833 AM","wacprep.exe","33664","ReadFile","\\office.git.ch\dfs\Data\EURDATA\GIT18\JNLS.DTA","END OF FILE","Offset: 7'091'712, Length: 384, Priority: Normal","O:\WinEUR\wacprep.exe  /company:GIT18"
"9:43:24.8244011 AM","wacprep.exe","33664","QueryStandardInformationFile","\\office.git.ch\dfs\Data\EURDATA\GIT18\JNLS.DTA","SUCCESS","AllocationSize: 7'094'272, EndOfFile: 7'092'864, NumberOfLinks: 1, DeletePending: False, Directory: False","O:\WinEUR\wacprep.exe  /company:GIT18"

(由于应用程序处于无限循环状态,因此记录了数千个此类记录。)

据我们了解,ReadFile调用应该成功:偏移量恰好在文件的边界内。然而,它失败了。 ProcMon报告END OF FILE,尽管我怀疑这仅仅是因为ReadFile返回!= 0并报告读取了0个字节。

在循环运行时,我们设法通过增加来自另一台机器的文件大小来解除阻止:

"Time of Day","Process Name","PID","Operation","Path","Result","Detail","Command Line"
"9:46:58.6204637 AM","wacprep.exe","33664","ReadFile","\\office.git.ch\dfs\Data\EURDATA\GIT18\JNLS.DTA","END OF FILE","Offset: 7'091'712, Length: 384, Priority: Normal","O:\WinEUR\wacprep.exe  /company:GIT18"
"9:46:58.6204810 AM","wacprep.exe","33664","QueryStandardInformationFile","\\office.git.ch\dfs\Data\EURDATA\GIT18\JNLS.DTA","SUCCESS","AllocationSize: 7'094'272, EndOfFile: 7'092'864, NumberOfLinks: 1, DeletePending: False, Directory: False","O:\WinEUR\wacprep.exe  /company:GIT18"
"9:46:58.7270730 AM","wacprep.exe","33664","ReadFile","\\office.git.ch\dfs\Data\EURDATA\GIT18\JNLS.DTA","SUCCESS","Offset: 7'091'712, Length: 384, Priority: Normal","O:\WinEUR\wacprep.exe  /company:GIT18"

0 个答案:

没有答案