Что заставляет CreateDirectory возвращать ERROR_ACCESS_DENIED? - PullRequest
4 голосов
/ 26 августа 2010

В другом вопросе мы установили, что да, CreateDirectory иногда дает сбой при недокументированном значении GetLastError ERROR_ACCESS_DENIED, и что правильный способ справиться с ситуацией - это, вероятно, попытаться еще раз несколько раз. Такой алгоритм легко реализовать, но его не так просто проверить, если вы не знаете, как его воспроизвести.

Мне не нужны теории, почему это происходит. Это может быть ошибка в Windows, да. Это также может быть разработано. В конечном счете, на данный момент, это не имеет значения, потому что Microsoft отправила поведение, и я должен справиться.

Мне также не нужно объяснение теории многозадачной операционной системы и того, как Windows реализует ее в целом. Я пишу системное программное обеспечение для жизни. Я мало что понимаю.

Теперь мне нужен надежный способ воспроизвести ошибку, чтобы я мог написать контрольный пример для кода, который справляется. Вот что я пробовал до сих пор:

  • Я написал тестовую программу P1, которая медленно и многократно перечисляет содержимое потенциального родителя. Кроме того, я написал тестовую программу P2, которая ничего не делает, но неоднократно пытается удалить и создать каталог в будущем родителе. Я полагал, что сохранение перечисления в течение длительного времени может сделать проблему более вероятной. Запуск P2 сам по себе приводит к периодическим сбоям (порядка каждых нескольких минут в течение приблизительно 10 миллисекунд). Запуск P1 и P2 одновременно, похоже, не делает сбои более частыми или продолжительными.

  • Я запускал два экземпляра P2 одновременно, и это, похоже, не делает сбои более частыми или продолжительными.

  • Я изменил P2, чтобы он мог создавать файлы в дополнение к каталогам и запускать их одновременно с P1, что, по-видимому, не делает сбои более частыми или продолжительными.

  • Я запускал P1 и несколько экземпляров P2 с разными параметрами одновременно, и это, похоже, не делает сбои более частыми или продолжительными.

  • Я написал тестовую программу P3, которая перемещает элементы в потенциальный родительский элемент и из него и запускала P3 одновременно с P2, и это, похоже, не делает сбои более частыми или продолжительными.

Есть еще идеи?

Ответы [ 2 ]

1 голос
/ 02 сентября 2010

Держу пари, что ваше перечисление / удаление / создание вызывает некоторые проблемы с синхронизацией с дескрипторами. Если CreateDirectory похож на CreateFile (и я предполагаю, что логика, лежащая в его основе, будет общей), то вы увидите поведение, аналогичное CreateFile:

Если вы вызываете CreateFile для файла, который ожидает удаления в результате предыдущий вызов DeleteFile, Функция не работает. Операционная система задерживает удаление файла до тех пор, пока все дескрипторы к файлу закрыты. GetLastError возвращает ERROR_ACCESS_DENIED.

1 голос
/ 27 августа 2010

Позвольте мне начать с двойной проверки, что я понимаю вопрос.Если вы запустите что-то вроде приведенного ниже фрагмента, вы ожидаете, что он в конечном итоге потерпит неудачу, верно?

while (true)
{
    System.IO.Directory.CreateDirectory( ".\\FooDir" );
    System.IO.Directory.Delete( ".\\FooDir" );
}

Если ваше приложение - единственная вещь, работающая в системе, у которой есть дескриптор, открытый для этого файла, тогда1004 * чувствует как ошибка.Так что знание версии ОС поможет.

С другой стороны, если в системе есть что-то еще, что удерживает ручку открытой какое-то время, то становится ли это ошибкой или нет, становится немного более размытым.Количество вещей, которые пытаются слепо использовать файлы и каталоги, может вас удивить.Например, наивный индексатор может зайти в этот каталог, перечислить его, найти файлы для индексации и т. Д. - и, если вы столкнетесь с ним, blammo.Подобный наивный антивирусный фильтр или какой-то другой фильтр файловой системы, возможно, тоже его высовывает (в этом случае это все еще похоже на ошибку).

Есть некоторые вещи, которые мы сделали вОС, чтобы попытаться предоставить такие услуги, как эти способы убраться с вашего пути.Воспроизводится ли это, если вы выключаете индексатор, выключаете ли вы какой-либо антивирус, любую антивирусную программу?Мы можем пойти оттуда, и, надеюсь, мы обнаружим, что более новые биты уже исправили это (я знаю, что в этом утверждении было много предположений).

Еще один относительно интересный момент состоит в том, что ERROR_ACCESS_DENIEDошибка Win32, сопоставленная с несколькими базовыми состояниями в системе (см., например, в этой статье ).Так что, если мы сможем копнуть немного глубже, мы сможем выяснить, что файловая система пытается сообщить приложению (если это больше, чем отказано в доступе).

Мы можем в конечном итоге начать разговор оможете ли вы, в дикой природе, предположить, что ваше приложение - это единственное, что копается в ваших файлах и каталогах.Вы, вероятно, можете догадаться, куда пойдет тот.

...