Имеется несколько вызовов ExReleaseFastMutex(). Как правило, они отрабатывают нормально,
но иногда вываливается БСОД с ошибкой IRQL_NOT_LESS_OR_EQUAL. Похоже, что вызов происходит
на уровне выше PASSIVE_LEVEL.
Почему, всё-таки, так происходит и как этого можно корректно избежать?
Здравствуйте, Freid, Вы писали:
F> Имеется несколько вызовов ExReleaseFastMutex(). Как правило, они отрабатывают нормально, F>но иногда вываливается БСОД с ошибкой IRQL_NOT_LESS_OR_EQUAL. Похоже, что вызов происходит F>на уровне выше PASSIVE_LEVEL. F> Почему, всё-таки, так происходит и как этого можно корректно избежать?
--
Это может происходить потому, что некоторые функции драйвера могут вызываться на разных IRQL.
C помощью функции KeGetCurrentIrql() Вы можете определить текущий IRQL и, в зависимости от его значения, вызывать или нет эту функцию (или, скорее всего, вызывать или нет ExAcquireFastMutex). По крайней мере Вы сможете определить, когда именно возникает эта ситуация и дальше уже пытаться решать эту проблему.
Спасибо за ответ.
Но появились некоторые проблемы. Я сделал следующую проверку:
if (KeGetKurrentIrql() >= DISPATCH_LEVEL)
return STATUS_FAILED;
Но завесы системы не прекратились, при чем в том же месте.
Кроме того, оказалось, что, на самом деле, завес происходит
после вызова KeSetEvent(). А SoftIce, в заголовке окна, пишет
ntoskrnl!KeReleaseMutex + 003B. Наверное, KeSetEvent() внутри
себя пытается освободить мютекс и виснет. Почему? Неизвестно...
Добрый день!
F>Кроме того, оказалось, что, на самом деле, завес происходит F>после вызова KeSetEvent(). А SoftIce, в заголовке окна, пишет F>ntoskrnl!KeReleaseMutex + 003B. Наверное, KeSetEvent() внутри F>себя пытается освободить мютекс и виснет. Почему? Неизвестно...
--
1. Проверьте, что KeSetEvent() не вызывается на IRQL > DISPATCH_LEVEL.
2. Случайно третий параметр WAIT при вызове функции KeSetEvent() не равен TRUE?
ГМ>1. Проверьте, что KeSetEvent() не вызывается на IRQL > DISPATCH_LEVEL.
ГМ>2. Случайно третий параметр WAIT при вызове функции KeSetEvent() не равен TRUE?
Поставил море DbgPrint-ов. IRQL = PASSIVE_LEVEL
Третий параметр — FALSE.
И абсолютно маловероятно, что KeSetEvent() поднимает уровень IRQL внутри себя...
Кроме того, 9 из 10 вызовов отрабатывают нормально.
Скажите, не существует ли каких нибудь временных ограничений на выполнение KeSetEvent?
Здравствуйте, Freid, Вы писали:
ГМ>>1. Проверьте, что KeSetEvent() не вызывается на IRQL > DISPATCH_LEVEL.
ГМ>>2. Случайно третий параметр WAIT при вызове функции KeSetEvent() не равен TRUE?
F>Поставил море DbgPrint-ов. IRQL = PASSIVE_LEVEL F>Третий параметр — FALSE. F>И абсолютно маловероятно, что KeSetEvent() поднимает уровень IRQL внутри себя... F>Кроме того, 9 из 10 вызовов отрабатывают нормально. F>Скажите, не существует ли каких нибудь временных ограничений на выполнение KeSetEvent?
Раз с IRQL у вас все нормально — то могут буть такие варианты.
1. PRKEVENT который вы передаете не валиден.
2. Надо видеть как вы получаете PRKEVENT. Кому сигналете, и в kernel или user mode находится ожидающий поток.
3. Так же — на каком уровне IRQL осуществляется ожидание, если это kernel -mode.
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
F>И абсолютно маловероятно, что KeSetEvent() поднимает уровень IRQL внутри себя...
--
Даже если и поднимает, то наверняка делает это корректно.
F>Кроме того, 9 из 10 вызовов отрабатывают нормально. F>Скажите, не существует ли каких нибудь временных ограничений на выполнение KeSetEvent?
--
Ничего подобного не слышал.
Как только был получен валидный указатель на объект KEVENT, им сразу же можно пользоваться.
Кстати, а как вы его (указатель) получаете? Если из HANDLE (т.е. с помощью функции ObReferenceObjectByHandle), то с какими параметрами она вызывается и в каком контексте?