В один из дней Брюс попытался, используя стандартную функцию проводника
Send To Compressed (zipped) Folder, упаковать
последние исходники
Process Monitor и послать мне.
Вместо обычного диалога о ходе упаковки, Проводник выдал ошибку:
Брюс был озадачен. Ошибка на первый взгляд не имела никакого смысла, так как
определенно он имел права на чтение выбранных файлов, он их только что закончил
редактировать, а сжатие не может затрагивать дополнительных файлов, которые
могли бы быть не найдены. Он повторил операцию сжатия, но ошибка снова
проявилась, правда, после другого количества файлов.
К счастью, в этот момент я появился на пороге его офиса, и он показал мне
странное поведение программы. Теперь мы двое были озадачены. Пришло время
провести расследование и инструментом в нем, как бы иронично это не выглядело,
послужит Process Monitor.
Мы запустили программу, воспроизвели ошибку, остановили
захват и начали просматривать тысячи операций в поисках ошибки. Мы увидели
несколько ошибок NOT FOUND в начале лога,
что обычно свидетельствует о попытке приложения проверить существование файла.
На самом деле их были сотни в начале лога, все были запросы на файл, в котором
будут помещены архивируемые файлы:
Это вызывало тревогу, но на самом деле не относилось к исследуемой нами
проблеме, так что я отложил дело до более удобного случая.
Несколько сотен событий после мы наткнулись на ошибку
SHARING VIOLATION:
Когда процесс открывает файл, он может определить, каким образом и при каких
условиях он хочет разделить его с другими процессами, в ходе того как файл будет
открыт. Три типа разделения - это чтение, запись, удаление, и каждый определяется
своим флагом, который процесс передает CreateFile
API. В операции, которая не удалась, Explorer не
определил ни один из флагов, что означает его нежелание разделять файл, что
видно в поле ShareMode:
Для удачного открытия файла тип разделения открывающего должен быть
совместим с разделением, которое разрешается процессом, уже открывшим файл.
Таким образом, объяснение этой ошибки состояло в том, что другой процесс уже
открыл файл.
Вернувшись к трассировке, мы определили, что ошибке предшествовало открытие
файла процессом Inort.exe. Закрытия файлов процессом
не видно, так как оно случилось гораздо позднее ситуации с ошибкой. Это
подтверждает, что конфликт разделения файла связан с
Inort, даже несмотря на то что процесс указал
возможность чтения, записи и удаления в своих условиях открытия файла.
Process Monitor закрыл дело - именно
Inort держал файл открытым и вызвал ошибку разделения
доступа с Explorer-ом, что и привело к появлению самой
первой ошибки. Нам необходимо было определить принадлежность
Inort для исправления ситуации. Process Monitor ответил и на этот вопрос:
eTrust, антивирусный сканер Computer Associates,
вероятно, открыл файл для сканирования на вирусы, но его действия и операция
Проводника наложились. Антивирус должен быть прозрачным для системы, так что в
данном случае это полностью ошибка eTrust.
Решением для Брюса стало исключение директории из списка сканируемых в реальном
времени каталогов.
Когда я вернулся в офис, воспроизвести ошибку мне не
удалось, я начал подозревать, что у меня другая версия антивируса, нежели чем у
Брюса. Страница процессов Process Monitor
действительно показала отличия. У меня была более поздняя версия -
7.01.0501.000:
Почему у нас разные версии, для меня до сих пор остается догадкой, ведь оба мы
используем образы, созданные и задеплоенные администраторами
Microsoft. Но зато стало ясно, что Computer
Associates исправила баг в новом релизе.
Теперь настала пора вернуться к неэффективной работе
процедуры сжатия в Проводнике. Я отследил компрессию одного файла и связанные с
ней операции. Даже в таком простом случае Explorer
открывает целевой ZIP-файл 14 раз, 12 раз до того как
он на самом деле создается - все с ошибкой NOT FOUND.
Кроме того, 19 раз выполняется обзор каталога. Избыточно открывается и исходный
файл - 28 раз, 17 раз читаются его свойства. Похоже, Explorer
предоставил eTrust массу возможностей для
возникновения ошибки...
Оставалось убедиться, что за всей это вакханалией стоит
именно Explorer^
Zipfldr.dll -
оригинальный файл для компрессии, он светился в большинстве записей, значит
именно он сам был причиной таких потерь. К тому же, учтите, что такие мусорные
операции будут только возрастать с увеличением количества сжимаемых файлов!
Однако совершенно очевидны пути для улучшения, и будем надеяться, что мы увидим
более эффективный алгоритм в Windows 7. Собственно, уже
известно, что движок архивации будет обновлен в Vista SP1.