Потеря сообщения (Event) от драйвера.

Тема в разделе "WASM.NT.KERNEL", создана пользователем shtepa_sergey, 4 июл 2008.

  1. shtepa_sergey

    shtepa_sergey New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    6
    Среда:
    Драйвер под ОС Windows.

    Алгоритм:
    Программа уровня пользователя формирует запрос DeviceIoControl.
    По запросу DeviceIoControl драйвер переводит событие в состояние "снято" и запускает на выполнение длительную операцию.
    Аппаратура по завершении операции формирует прерывание.
    Обработчик прерываний снимает прерывание и устанавливает событие в "установлено".
    Программа уровня пользователя делает WaitForSingleObject.

    Проблема:
    Таким образом, после запроса длительной опреации WaitForSingleObject гарантированно должно завиксировать установку события, однако с некоторой вероятностью, этого не происходит! Где-то в 1 случае из 10 тыс. WaitForSingleObject выходит по таймауту. Таймаут стремиться к бесконечности (при INFINITY виснет напроч).

    Самое интересное, если сразу после выхода из функции WaitForSingleObject по таймауту опросить событие, то оно в состоянии "установлено" и на уровне ядра с помощью DbgView видно что событие было установлено и после выхода по таймауту оставалось установлено!!!

    Можно конечно переделать алгоритм, IRP запрос на обслуживание отложить, а по прерыванию его завершить, но менять структуру уже не хочется.

    Можно также дважды делать WaitForSingleObject, однако это как то не прилично.

    Может кто что подскажет.
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Без кода трудно будет сказать что-то, может быть при какихто обстоятельствах теряется вызов к KeSetEvent или что-то еще..
     
  3. shtepa_sergey

    shtepa_sergey New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    6
    Кода слишком много, чтобы его приводить, к сожалению...
    Теория про то, что теряется вызов я проработал. KeSetEvent всегда выполняется после обработки прерывния и установлен: слово ((ULONG*)(pEvent))[1] == 1.

    Может если кто знает, при правильно реализованном алгоритме такая ситуация как у меня под ОС WindowsXP вообще возможна? Или это всё же моя ошибка? Не хочется искать чёрную кошку в тёмной комнате когда её там нет.

    Интересно то, что ошибка увеличивает вероятнсть своего проявления при увеличении интенсивности обмена.
     
  4. shtepa_sergey

    shtepa_sergey New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    6
    Ура форум в доступе!
    Нашёл ошибку сам.
    Проблема была в алгоритме. Нельзя выставить событие в обработчике прерываний, так как согласно DDK KeSetEvent вызывается на уровне IRQL<=DISPATCH_LEVEL.

    Исправил проблему следующим образом:
    В обработчике прерывания ставлю в очередь запуск DPC функции. DPC функция выполняется после завершения обработки прерывания на уровне DISPATCH_LEVEL и выставляет событие.
    Самое забавное, что с такой ошибкой драйвер вообще довольно упешно работал, ошибка проявлялась довольно редко!
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Вот так вот не читать допустимые IRQL в ддк :))

    Вообще, когда ты писал, я думал что ты делаешь какойнить dpc или workitem... а оказалось ты напрямую ставил:)
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Да,кстати, специально, чтобы ловить такие и многие другие ошибки, есть Check Build сборка ядра.
    Например код KeSetEvent начинается с:
    ASSERT_EVENT(Event);
    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    Чекбилд ядра бы сразу отловил это дело и выдал ассерт.
    + Driver Verifier тоже много чего ловит.
    + Static Driver Verifier (или как он там называется в WDK, который анализирует исходный код)

    Полезные штуки, а мало кто использует, к сожалению.
     
  7. shtepa_sergey

    shtepa_sergey New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    6
    Всё хорошо, но есть проблемка.
    Driver verifier из tools DDK так негативно воспринял мой драйвер, что после настройки и перезагрузки возникала критическая ошибка и винда больше не загружалась.

    WDK посмотрю.

    А вот Check Build винды я как то и не надеялся найти дистрибутив. Если не трудно дайте ссылочку.

    Заранее благодарен за помощь на моём ПУТИ.
     
  8. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    Verifier делает BSOD при ошибках. Цепляй WinDBG - увидишь что и где.
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Набрать в гугле "Windows XP SP2 Checked Build" религия не позволяет? Первая ссылка на скачку с сайта MS.
     
  10. shtepa_sergey

    shtepa_sergey New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    6
    Позволила, набрал, скачал. Действительно первая.

    Предчувствую, что ещё долгое время проведу занимаясь отладкой.

    Всем спасибо.
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    весь дистриб не ставь, возьми оттуда тока ntoskrnl и hal и пропиши как ядро и хал в boot.ini соотв. ключами
     
  12. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    http://www.osronline.com/ в правой колонке "THE LATEST" всегда есть ссылка на Checked Build Downloads, где перечислены все публично доступные дебужные билды.