这几天我一直在追一个非常神秘的错误,它似乎围绕着(ZLIB 库);它每月左右发生一次,并且仅在某些特定的生产环境中发生。以下是代码的作用:
- 程序调用
gzopen
写入文件X
。 - 程序将数据写入文件,执行几个
gzwrite
. - 程序最终调用
gzclose
它刷新文件。
通常,一切正常,文件X
有效;它以 CRC 和源流的长度正确终止。
但是,在其中一个故障中,我观察到这X
是损坏的:数据的开头是正确的,但是从 offset 开始0x00302000
,每个字节都是空的。即使是编码 CRC 和长度的最后八个字节也为零。但是,该文件具有正确的大小!更糟糕的是:同一个系统在几分钟前成功压缩了一个非常相似的文件。
注意:我们使用的 ZLIB.DLL 版本为 1.1.3;是的,我知道,它包含一些安全漏洞,我们应该升级到最新的 ZLIB 1.2.3,但在找到归零的原因之前,我不想更改我的设置中的任何内容。
我认为我已经排除了内存损坏(顺便说一下,损坏的内存堆怎么会干扰fwrite
到它只向输出流写入零?这是否合理?),打开/写入/关闭流的循环很简单,没有发现我能发现的任何缺陷,代码不会分配/释放/弄乱 ZLIB 中的结构(这可能是个问题,因为 ZLIB 链接到另一个 C 库而不是我的应用程序 DLL),所以我只能怀疑系统中的其他元素。
不知何故,我倾向于对 C 库 (CRTDLL.DLL)、Win32 API、NTFS 堆栈、I/O 堆栈、低级设备驱动程序、硬盘固件和硬盘本身充满信心......是的,我也倾向于相信 Visual C++ 2008 会生成正确的二进制文件,至少在这种情况下是这样 ;-)
那么,我是否正确怀疑杀毒软件可能是罪魁祸首?ZLIB 应该谨慎,因为至少 Kaspersky 将 DLL 识别为可能的威胁。但是,如果(错误地)发现感染,杀毒软件只写零而不是数据在政治上是否正确?或者这可能是防病毒软件中的错误?
还是我完全错过了重点?