ZLIB в Windows: gzopen/gzwrite/gzclose создает кастрированный выходной файл / виноват антивирус?

Я уже несколько дней гоняюсь за очень загадочной ошибкой, которая, похоже, связана с (библиотекой ZLIB); это происходит примерно раз в месяц и только в некоторых конкретных производственных средах. Вот что делает код:

  1. Программа вызывает gzopen для записи в файл X.
  2. Программа записывает данные в файл, делая несколько gzwrite.
  3. Наконец, программа вызывает gzclose, который очищает файл.

Обычно все работает нормально и файл X действителен; он правильно завершается с помощью CRC и длины исходного потока.

Однако в одном из сбоев я наблюдаю, что X поврежден: начало данных правильное, но начиная со смещения 0x00302000 каждый байт равен нулю. Даже восемь последних байтов, которые кодируют CRC и длину, равны нулю. Тем не менее, файл имеет правильный размер! И что еще хуже: та же система успешно сжала очень похожий файл несколькими минутами ранее.

Примечание. Используемая нами ZLIB.DLL имеет версию 1.1.3; да, я знаю, что в ней есть некоторые дыры в безопасности, и мы должны обновиться до последней версии ZLIB 1.2.3, но я не хочу ничего менять в своих настройках, пока не найду причину обнуления.

Я думаю, что я исключил повреждение памяти (кстати, как поврежденная куча памяти могла нарушить fwrite настолько, что он записывает в выходной поток только нули? поток прост и не выявляет каких-либо дефектов, которые я могу обнаружить, код не выделяет/не освобождает/не путается со структурами в ZLIB (что может быть проблемой, поскольку ZLIB связан с другой библиотекой C, чем библиотеки DLL моего приложения), поэтому я могу только подозревать другие элементы в системе.

Почему-то я склонен доверять библиотеке C (CRTDLL.DLL), Win32 API, стеку NTFS, стеку ввода-вывода, низкоуровневым драйверам устройств, прошивке жестких дисков и самим жестким дискам... И да, я также склонен полагать, что Visual C++ 2008 создает правильные двоичные файлы, по крайней мере, в этом случае ;-)

Итак, правильно ли я подозреваю, что антивирусное программное обеспечение может быть виновником? С ZLIB следует быть осторожным, так как по крайней мере Касперский распознает DLL как возможную угрозу. Но будет ли политкорректно, если антивирус просто запишет нули вместо данных, если заражение будет (неправильно) обнаружено? А может это глюк антивируса?

Или я совсем упускаю суть?


person Pierre Arnaud    schedule 02.06.2009    source источник


Ответы (1)


Не зная ничего другого, я бы заподозрил ваш код, а не код антивируса.

Потребуется простая ошибка, чтобы записать правильную длину данных в файл, но передать неправильный буфер, что приведет к «всем нулям» в качестве данных в файле.

Простые ошибки, которые трудно обнаружить, иногда приводят к очень большой путанице, как у вас.

Если бы я решал эту проблему, я бы:

  • упрощать упрощать упрощать, пока проблема не прекратилась. затем постепенно добавляйте сложность.
  • проверьте свои указатели и арифметику указателей
  • убедитесь, что вы правильно очищаете и закрываете файл
  • используйте распределитель, который хранит байты маркеров в выделенных буферах, например 0xAA, а не 0x00. Таким образом, вы можете увидеть, записывается ли в файл ваш (обнуленный) буфер.
  • пройти все это в отладчике

В нормальных условиях данные GZIP никогда не будут иметь длинную последовательность нулей. Они будут свернуты в словарь и код длины.

person Cheeso    schedule 02.06.2009
comment
Вам за советы. Думаю, я все перепроверил, но вы правы, я должен заменить распределитель памяти, чтобы убедиться, а затем через несколько недель посмотреть, не возникнет ли проблема в производстве... Я также заметил, что простой файл copy (fopen A/fopen B/fread A/fwrite B/fclose A/fclose B) создает файл B нужного размера, но содержит только нули; но это происходит только тогда, когда возникает описанная выше проблема. - person Pierre Arnaud; 03.06.2009