ECk Я так понял livekd для ХР не актуален. Это раньше нельз было локально дебажить. К тому же у меня проблемы при вызове DriverEntry. Т.е. надо чтобы отладчик уже был загружен и поймал этот багчек.
Запускаем ОДНОВРЕМЕННО две копии твоего драйвера на РАЗНЫХ процессорах. Ты делаешь cli из обоих драйверов и начинаешь править код в памяти. В таком случае драйвера будут работать ПАРАЛЛЕЛЬНО(одновременно если угодно). Замечу, что код драйвера на каждом процессоре НЕ БУДЕТ прерван другой задачей пока ты не сделаешь sti. ЗЫ Я тоже заморачивался с задачей блокировки ВСЕХ процессоров - выход один DPC на каждый процессор. И уже в коде DPC делай cli/sti. смотри: DDK KeSetTargetProcessorDpc() Экспортируемая переменная: KeNumberProcessors делашь цикл for(int i=0;i<KeNumberProcessors;i++) { KeSetTargetProcessorDpc(MyDPC,i); } Цитата с которой я полностью согласен:
netex Спасибо, конечно, что принял участие в беседе. - мощно. А почему две, а не 15 ? Да и нет задачи блокировки всех процессоров. ... вообщем не надо так по-чёрному курить До меня только сейчас дошло... ты, наверное используешь какую-то альтернативную ОС-ку, которая запускает свои копии на каждом процессоре отдельно и соответственно одновременно грузит все драйвера на каждом процессоре ?
Значит я просто в тему не въехал. Но если нужно будет заблокировать все процы, пояснение см.выше ЗЫ Эта альтернативная ОС зовется виндой Она бывает еще и многозадачная, а если ее поставить на SMP машину, будет вообще трактор! А в тракторе том есть штуковина affinity... Остальное лирика...
netex Спасибо. Я понял. Если нужно будет заглушить все процы, то можно смело обращаться к тебе это всё, конечно, хорошо... Но я, надеюсь, ты не думаешь, что DriverEntry начнёт одновременно выполнятся на нескольких процах.
Каким раком юзермодный отладчик поймает багчек? livekd и Windbg в режиме локальной отладки могут же только пассивно наблюдать за системой, но никак не вмешиваться в работу, расставлять брекпоинты и ловить багчеки. это под силу только всяким сайсерам и софтайсам, либо при отладке с другого компа. Или я что-то в этой жизни упустил? отладчик который запускается по ключу /debug встроен в ядро, но активно работать он может только при подключении с другого компа
Если ты сделаешь копию своего драйвера (к примеру Drv1.sys и Drv2.sys) и запустишь обе, то есть шанс что они попадут на разные процы. Вот тебе пример который все пояснит: Ты написал крутой драйвер по модификации кода. Вася Пупкин украл твои секреты и сделал похожий драйвер, который делает тоже самое. Если юзер(который ничего не знает о внутренности дров) установит у себя обе ваши проги, то они будут конфликтовать. Блокировку тебе нужно использовать если только хочешь получить МОНОПОЛЬНЫЙ доступ к ресурсу. В твоем случае модифицировать память.
Great livekd - вообще не отладчик. это пришлёпка к "Debugging Tools for Windows" которая делает возможным локальную отладку (т.е. без двух компов.). Штука нормальная, но мне не поможет. - это понятно, что никаким. надо где-то sice раздобыть. Кстати, кажется можно зарегить калбэк на багчек. А как что нибудь путное при этом на экран вывести ?
netex ... ты писать не пробовал ? Я думаю, в жанре научной фантастики ты бы мог пару премий заработать С Васей Пупкиным много чего случается, но у меня всё проще.
я в курсе что это) я его аналог уже написал. отладку еще раз говорю он не делает возможным) только наблюдение, но не активное участие и нафига тебе оно? ну напишешь ты драйвер который регистрирует колбек, вывести ты вряд ли чтото сможешь куда либо кроме как на синий экран, а вряд ли ты сможешь вывести что-то более умное, чем выведет автоанализатор винды
что-то я вообще не догоняю... Написал функцию которая в файл пишет отладочную информацию. Попробовал несколько раз остановить/запустить устройство. Через некоторе кол-во попыток BSOD NO_MORE_IRP_STACK_LOCATIONS. Такого багчека ещё не было Даже crash-dump создал. Какая может быть логика в том что время от времени возникает NO_MORE_IRP_STACK_LOCATIONS ?
видимо ты неправильно обрабатываешь ирп. покажи !analyze -v и сбойную функцию-обработчик irp в твоем дрове
вот analize -v: Код (Text): BUGCHECK_STR: 0x35 PROCESS_NAME: System LOCK_ADDRESS: 8055a560 -- (!locks 8055a560) Resource @ nt!IopDeviceTreeLock (0x8055a560) Shared 1 owning threads Threads: 821c6b30-01<*> 1 total locks, 1 locks currently held PNP_TRIAGE: Lock address : 0x8055a560 Thread Count : 1 Thread address: 0x821c6b30 Thread wait : 0xbcc LAST_CONTROL_TRANSFER: from 804eee98 to 804f9c37 STACK_TEXT: f88c7150 804eee98 00000035 818c64b8 00000000 nt!KeBugCheckEx+0x1b f88c7168 a9b46bb4 a9b3dcc0 81899000 a9b39420 nt!IopfCallDriver+0x18 f88c781c a9b44fc0 81eae248 e27bd1fe 00000000 serial!GetDiskInfo+0x1e2 [z:\protect.c @ 291] f88c7830 8058006a 81eae248 81899000 00000000 serial!DriverEntry+0x140 [z:\initunlo.c @ 244] f88c7900 8058e1df 80000860 00000000 f88c7900 nt!IopLoadDriver+0x66c f88c7944 805e5ad7 e26dd370 00000001 80000860 nt!PipCallDriverAddDeviceQueryRoutine+0x235 f88c7990 805e5e0c f88c7a1c e26dd35c f88c79f0 nt!RtlpCallQueryRegistryRoutine+0x3b1 f88c79f4 8058fa67 00000000 00000084 00000001 nt!RtlQueryRegistryValues+0x2a6 f88c7ac8 80590f24 00000000 00000001 f88c7d5c nt!PipCallDriverAddDevice+0x261 f88c7d24 805914ba 82144b88 00000001 00000000 nt!PipProcessDevNodeTree+0x1a4 f88c7d54 804f66bc 00000003 8055a5c0 8056375c nt!PiRestartDevice+0x80 f88c7d7c 80537757 00000000 00000000 821c6b30 nt!PipDeviceActionWorker+0x168 f88c7dac 805ce794 00000000 00000000 00000000 nt!ExpWorkerThread+0xef f88c7ddc 805450ce 80537668 00000001 00000000 nt!PspSystemThreadStartup+0x34 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 STACK_COMMAND: kb FOLLOWUP_IP: serial!GetDiskInfo+1e2 [z:\protect.c @ 291] a9b46bb4 3d03010000 cmp eax,103h FAULTING_SOURCE_CODE: 287: #if DBG 288: DbgPrint("serial.sys[GetDiskInfo]: IoCallDriver - success\n"); 289: #endif 290: > 291: if(status == STATUS_PENDING) 292: { 293: #if DBG 294: DbgPrint("serial.sys[GetDiskInfo]: IoCallDriver return STATUS_PENDING\nWaiting...\n"); 295: #endif 296: //timeout.QuadPart = -100000000; //timeout 10s SYMBOL_STACK_INDEX: 2 а ирп я создаю для другого драйвера: Код (Text): ... NTSTATUS status; OBJECT_ATTRIBUTES oa; PIRP pIRP = NULL; PIO_STACK_LOCATION pNextStack; PDEVICE_OBJECT pDeviceObject; PFILE_OBJECT pFileObject; UNICODE_STRING usPhysicalDriveName; WCHAR wcPhysicalDriveName[] = L"\\??\\PhysicalDrive0"; BOOL bRes = FALSE; GETVERSIONINPARAMS VersionParams; IO_STATUS_BLOCK iosb; KEVENT Event; SENDCMDINPARAMS scip; BYTE IdOutCmd [sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; wcPhysicalDriveName[17] = drive + L'0'; RtlInitUnicodeString(&usPhysicalDriveName, wcPhysicalDriveName); InitializeObjectAttributes(&oa, &usPhysicalDriveName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); status = IoGetDeviceObjectPointer(&usPhysicalDriveName, GENERIC_READ | GENERIC_WRITE, &pFileObject, &pDeviceObject ); if(status != STATUS_SUCCESS) { #if DBG DbgPrint("serial.sys[GetDiskInfo]: IoGetDeviceObjectPointer fail\n"); #endif return bRes; } KeInitializeEvent(&Event, NotificationEvent, FALSE); pIRP = IoBuildDeviceIoControlRequest(SMART_GET_VERSION, pDeviceObject, NULL, 0, &VersionParams, sizeof(VersionParams), FALSE, &Event, &iosb); if(pIRP == NULL) { ObDereferenceObject(pFileObject); return bRes; } pIRP->Tail.Overlay.OriginalFileObject = pFileObject; pIRP->RequestorMode = KernelMode; pNextStack = IoGetNextIrpStackLocation(pIRP); pNextStack->FileObject = pFileObject; pNextStack->MajorFunction = IRP_MJ_DEVICE_CONTROL; status = IoCallDriver(pDeviceObject, pIRP); if(status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } if(status != STATUS_SUCCESS) { ObDereferenceObject(pFileObject); return bRes; } ... KeClearEvent(&Event); pIRP = IoBuildDeviceIoControlRequest(SMART_RCV_DRIVE_DATA, pDeviceObject, &scip, sizeof(SENDCMDINPARAMS) - 1, &IdOutCmd, sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, FALSE, &Event, &iosb); if(pIRP == NULL) { ObDereferenceObject(pFileObject); return bRes; } pIRP->Tail.Overlay.OriginalFileObject = pFileObject; pIRP->RequestorMode = KernelMode; pNextStack = IoGetNextIrpStackLocation(pIRP); pNextStack->FileObject = pFileObject; pNextStack->MajorFunction = IRP_MJ_DEVICE_CONTROL; status = IoCallDriver(pDeviceObject, pIRP); if(status == STATUS_PENDING) // <- сюда указывает ip в краше { ... }
этот бсод возникает, если Irp->CurrentLocation <= 1, то есть у pDeviceObject у тебя StackSize=0 во время вызова IoBuildDeviceIoControlRequest но так вроде не бывает) первый и единственный параметр багчека - указатель на IRP. покажи его дамп через !irp
это единственное условие по которому он генерируется в единственном месте в IopfCallDriver: Код (Text): Irp->CurrentLocation--; if (Irp->CurrentLocation <= 0) { KiBugCheck3( NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR) Irp, 0, 0 ); } (WRK sources)