Может быть очень простые: 1. Если по таймеру вызвалась DPC процедура, и выполняется достаточно долго, что приходит время вызвать снова эту DPC процедуру по таймеру, то вызовится ли она, прервав первую, или дождётся завершения первой? 2. Планировщик(диспетчер ядра) потоков вызывается на DISPATCH LEVEL'е? Но тогда, если есть работющая PDC-процедура, и вдруг случилось прерывание по таймеру, управление перешло одной из функций диспетчера ядра? Или что, DPC будет продолжать выполняться? (Помоему, последнее...) 3. Когда происходит PageFault, то кто его обрабатывает? На каком IRQL? Спасибо за помощь...
Прервать DPC может только прерывание с IRQL > DISPATCH, а другая DPC не может. Но вторая DPC может быть запущена одновременно с первой на другом процессоре. DPC прервана не будет, планировщик сможет работать с потоками только тогда, когда IRQL станет меньше DISPATCH. PageFault - аппаратное исключение процессора, и оно не может быть замаскировано никаким IRQL, но на IRQL >= DISPATCH оно не может быть обработано SEH и вызовет неминуемый крах системы.
Небольшое дополнение к 3. PageFault происходит при обращении к странице, отсутствующей в физической памяти. Обрабатывается обработчиком прерывания №14 KiTrap0E, но главная работа делается функцией MmAccessFault и файловой системой. MmAccessFault работает на IRQL = PASSIVE_LEVEL с выключенными APC или на IRQL = APC_LEVEL. Если отсутствующая страница находится на диске, то обработчик будет ждать, пока файловая система прочитает её с диска. Т.к. ожидание невозможно на повышенных IRQL, то PageFault на IRQL > APC_LEVEL ведет к краху.
А могу ли я сам установить обработчик ислючений глобально на всю систему? Я знаю, что если мне в программе потребуется отловить какое то исключение, то я использую просто блок __try __except. А вот если я хочу, чтоб глобально был установлен обработчик по умолчанию. Например, пересчитать сколько каких исключений возникло в системе.
А могу ли я сам установить обработчик ислючений глобально на всю систему?А какие исключения ты хочешь обрабатывать в рамках всей ситемы (вместо системы)? Сами исключения могут возникать как в пользовательском режиме, так и в режиме ядра.Почти все исключения вызывают в конечном итоге KiDispatchException(описана у Гарри Неббета в справочнике по базовым функциям).В пользовательском режиме верхний обработчик устанавливается SetUnhandledExceptionFilter если и он не обработает то процесс закроется. А в режиме ядра наверно только через IDT зная номер исключения.Необрабатываемые исключения режима ядра заглушены функцией КеBugCheckEx вызывающей BSOD. А те которые обрабатываются по-моему трогать не надо например обработка подкачки страницы. Если хочешь узнать сколько произошло ошибок страниц пользуйся ZwQuerySystemInformation с SystemProcessesAndThreadsInformation. Извините если что не так, слишком пьян...
DESTROY_ru - да нет, вот именно это меня и интересовало: в юзер моде я, значит, могу SetUnhandledExceptionFilter использовать, а в кернел моде только через IDT, то есть нет чего то, типа SetUnhandledExceptionFilter... Ясн. А пример с "Например, пересчитать сколько каких исключений возникло в системе." я привёл без какого то нибыло смысла. Понятно, что в системе должны быть эти счётчики по-любому. Спасибо, парни, за объяснения. Я, правда, уже сам нашёл книжку Соломона Руссиновича о win2k. А вот Неббет есть в каких вариантах(электронный или аналоговый?) и на каких языках (En/Ru) - надо бы найти... Очень это интересно всё.
"Внутреннее устройство Windows2000" Соломона/Руссиновича я бы посоветовал прочитать в первую очередь. В этой книге описана филосовия Windows, как она устроена, из каких подсистем состоит, описана каждая подсистема, и их взаимодействие, но с точки зрения практического програмирования она бесполезна, та нет ни одного кусочка исходников.С другой стороны Гарри Неббет это справочник(на русском)когда я покупал стоил 200р.В нем мало что объясняется но идет перечисление функций Native API какие параметры на входе, что возвращает, и кратенькое описание. Есть доволно полезные куски кода.Справочник, он всегда справочник...Также могу посоветовать прочитать Свена Шрайбера "Недокументированные возможности Windows2000" когда приступишь к практике написания программ нулевого кольца защиты(Драйверов)в этой книге и теория и практика...
Я уже приступил... чуть чуть. Тестовый драйвер раз из десяти вылетает и я вижу BSOD Догадываюсь, что в DPC баг... пишет, что IRQL_NOT_LESS_OR_EQUAL, только вот сама по себе она простая... А из за чего ещё может быть такое? Если всё остальное работает на PASSIVE_LEVEL'е. Хотя, наверное, мне придётся самому искать ошибку...
Телепаты сейчас в отпуске, так что для определения причины ошибки нужно увидеть код. Догадываюсь, что ты обращаешся к подкачиваемой памяти из DPC, либо внутри кода закрытого спинлоком.
Я и без телепатов понимаю, что это из за этого должно быть... только вроде я использую в DPC только глобальные переменные (которые поидее должны быть неподкачиваемые), плюс KeSetEvent... Ну и самое интересное, что вылетает так где то раз из десяти. То есть обычно работает нормально... Хр знает, что там с памятью... Ладно, буду сам разбираться.
Значит причина в неправильной фазе луны. Попробуй скомпилировать драйвер в полнолуние, и сплюнь через левое плечо.
Я попробую понять это, хотя бы для того, чтобы уложить кашу в голове, если я не прав меня поправят и я стану на чуть-чуть умнее. Поток работающий на IRQL >= DISPATCH_LEVEL не может ждать освобождение ресурса! Если бы такая ситуация произошла пришлось бы работать диспетчеру, который в свою очередь тоже работает на DISPATCH_LEVEL. Вот и получается, что диспетчер не может начать работау, т.к. выполняется поток с уровнем DISPATCH, отсюда и крах операционной системы. Но ведь это касается только монопроцессорной системы, какова будет ситуация во многопроцессорной системе?