На каких уровнях IRQL, в ядре можно вызывать эти ф-ции ? Делаю лог-журнал для firewall. Один поток (главный) считывает данные и помещает в очередь (с двумя сетевухами DISPATH_LEVEL) Другой поток (PASSIVE_LEVEL) берёт из очереди данные и пишет в файл. Работает так некоторое время и вываливается BSOD Bug Check 0x7F: UNEXPECTED_KERNEL_MODE_TRAP Адреса нету (This signifies that a trap was generated by the Intel CPU which the kernel did not catch.) Сначала избавился от memcpy - не помогло, теперь грешу на sprintf, но свою ф-цию писать накладно В MSDN даётся только для юзермод Есть мысли, пожелания, предположения ? Ж P.S. Очередь - неподкачиваемый пул
Если память неподкачиваемая, то на любом IRQL, если подкачиваемая, то < DISPATH_LEVEL А как дела обстоят с синхронизацией? Вот код, который я использовал для ведения лога на высоких IRQL, и вроде он всегда нормально работает: Код (Text): void AddLog(PCHAR Message) { KIRQL OldIrql; KeAcquireSpinLock(&LogSpinLock, &OldIrql); if (MSG_BUFF_SIZE - strlen(SendMsgs) > strlen(Message) + 3) { strcat(SendMsgs, Message); strcat(SendMsgs, "\x0D\x0A"); } KeReleaseSpinLock(&LogSpinLock, OldIrql); } LogPrint(PCH Format, ...) { CHAR Buffer[1024]; va_list ap; va_start (ap, Format); _vsnprintf (Buffer, sizeof( Buffer ), Format, ap); va_end (ap); AddLog(Buffer); }
Ms Rem Технология именно такая же Есть у меня жестокое подозрение, что это деление на 0, т.к. уровень диспетчера, то BugCheck может "пролетать мимо кассы". Делается очередь на 100 структур есть счётчик tail(хвоста) и head(головы) при совпадении - очередь пуста. При помещении в очередь вычисляется новый head=head+1 с помощью целочисленного деления на длину очереди (берётся остаток) усножаем на sizeof(Structra) и прибавляем указатель на начало очереди Т.о. добиваемся заполнения по кругу Код (Text): |--->| ----- | | | | | | | | | | | | | ----- | |<---| Деление на 0 при уровне диспетчера BugCheck-м перехватывается ?
The first parameter displayed on the blue screen specifies the trap number. .... 0x00000008, or Double Fault, is when an exception occurs while trying to call the handler for a prior exception. Normally, the two exceptions can be handled serially. However, there are several exceptions that cannot be handled serially, and in this situation the processor signals a double fault. This is almost always caused by hardware problems. У меня именно это ( Это в WMVare конечно, придётся на живой машине пробовать
memcpy можно звать на любом IRQL, лишь бы помять, к которой она обращается, была неподкачиваема. Про sprintf точно не скажу, но, например, DbgPrint можно звать только на PASSIVE_LEVEL, если в спецификаторе используется unicode (%C, %S, %lc, %ls, %wc, %ws, %wZ). RtlCompareUnicodeString можно звать только на PASSIVE_LEVEL, по той причине, что она обращается к таблицам национальных раскладок, а они загружены в подкачиваемую память. Если DbgPrint работает с юникодом, то, видимо, тоже к ним обращается. Возможно то же самое делает и swprintf и sprintf, если форматируют юникод.
Проблема была найдена, только в другом месте Прототип ф-ции KeReleaseSpinLock PROTO STDCALL WORD, WORD Вызываем Код (Text): LogPrintf proc uses esi edi edx Fmt:PCHAR, Arg:UINT ; ...... local entry :QUEUE_ENTRY local irql :KIRQL; определён как BYTE ...... invoke KeAcquireSpinLock, offset Queue.guard, addr irql ...... invoke KeReleaseSpinLock offset Queue.guard, irql Что получаем при дизассемблировании 8-( ) Код (Text): mov al,[ebp][-0000009D] movzx ax,al push ax; <- почему WORD ? push 0000136F4 call KeReleaseSpinLock А получаем ДЫРУ В СТЭКЕ В 2 БАЙТА >8-( ) В ядре это BSOD. Интересно что это MASM криво асмит или прототип в другом месте по другому описан ? Если прототип, то MASM обычно ругается
У меня такая же фигня была с WRITE_PORT_UCHAR и т.п. Проишлось делать так: Код (Text): mov eax, XXXXXXXX and eax, 0FFh invoke WRITE_PORT_UCHAR, 42h, eax Уже не помню, но кажется это именно масм косячит.