阅读:1194回复:8
非典型性page fault,令人喷血的故障!救命!
我创建了一个带有DeviceName的Device Object,并且为之创建了Symbol Link。
在用户态可以使用CreateFile打开该设备,并且可以正常进行所有操作,但偏偏在CloseHandle时,系统必page fault。用softice在IRP_MJ_CLOSE的Dispatch Function设断点,居然拦截不住,因为该fault是在系统调用Dispatch之前出现。 原来是没问题的,但不知道什么时候出这鬼样,我还从来没碰到过。有经验的战友指点一下谢谢! [编辑 - 4/8/03 by daor] |
|
沙发#
发布于:2003-04-09 11:36
另外我把fido对edo的几乎所有的操作都注释掉了,只保证在系统对fido发出IRP_MN_REMOVE_DEVICE时,同时删除edo及其SymbolicLink。
还有,这个edo不会收到任何IRP_MJ_PNP,因为它是一个孤苦零丁的Device Object,作专门用途。 [编辑 - 4/9/03 by daor] |
|
板凳#
发布于:2003-04-09 11:21
这是一个总线过滤驱动程序,事实上,这个驱动程序都写完了,而且曾经正常使用过一段时间,正要向主管交差,订机票离开这个城市,怎知道在完善代码时,什么时候居然冒出这个问题,而且代码怎么改回去都不行,奇怪得很。我现在把代码改到最简化了,对这个设备对象的操作只有以下几段:
1.创建该EDO并且初始化: Usf_AddDevice( IN PDEVICE_OBJECT fido, IN PIRP Irp ) { // 创建过滤驱动程序的主FiDO,并初始化... .... /* 由于FiDO无法与Application打交道,因此创建一个额外的、不连接到任何底层的设备对象edo,并初始化: */ // 创建EDO t<<\"Creating EDO...\\n\"; PDEVICE_OBJECT edo; WCHAR namebuf[64]; static LONG numextra = -1; _snwprintf(namebuf, 64, L\"\\\\Device\\\\UsfMonitor%d\", InterlockedIncrement(&numextra)); UNICODE_STRING edoname; RtlInitUnicodeString(&edoname, namebuf); status = IoCreateDevice(DriverObject, sizeof(EDO_DEVICE_EXTENSION), &edoname, FILE_DEVICE_UNKNOWN, 0, FALSE, &edo); if (!NT_SUCCESS(status)) { t<<\"Create EDO failed!\\n\"; IoDetachDevice(pFdx->CommonData.LowerDeviceObject); IoDeleteDevice(fido); return status; } // 初始化EDO设备扩展 t<<\"Start to initialize EDO DeviceExtension\\n\"; PEDO_DEVICE_EXTENSION pEdx = (PEDO_DEVICE_EXTENSION) edo->DeviceExtension; pEdx->CommonData.Flag = EDO_EXTENSION; // 创建SymbolickLink t<<\"Creating SymbolickLink for EDO...\\n\"; WCHAR symname[64]; UNICODE_STRING SymLink; _snwprintf(symname, 64, L\"\\\\??\\\\USFilter%d\", numextra ); RtlInitUnicodeString( &SymLink , symname); status = IoCreateSymbolicLink( &SymLink, &edoname ); if (!NT_SUCCESS(status)) { t<<\"...Failed!\\n\"; IoDetachDevice(pFdx->CommonData.LowerDeviceObject); IoDeleteDevice(fido); IoDeleteDevice(edo); return status; } pEdx->pSymLink = &SymLink; t<<\"...OK!\\n\"; edo->Flags |= DO_BUFFERED_IO; edo->Flags &= ~DO_DEVICE_INITIALIZING; // 记得建立fido和edo的相互连接! pEdx->Fdo = fido; pFdx->Edo = edo; t<<\"Create EDO OK!\\n\"; return status; } 2.IRP_MJ_CREATE的分派: NTSTATUS Usf_Create ( IN PDEVICE_OBJECT fido, IN PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION iostack = IoGetCurrentIrpStackLocation(Irp); PCOMMON_EXTENSION pdx = (PCOMMON_EXTENSION) fido->DeviceExtension; if(pdx->Flag == EDO_EXTENSION) // 对edo的操作 { status = STATUS_SUCCESS; Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } else { //Fido的操作} return STATUS_SUCCESS; } 3. IRP_MJ_CLOSE的分派 NTSTATUS Usf_Close ( IN PDEVICE_OBJECT fido, IN PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION iostack = IoGetCurrentIrpStackLocation(Irp); PCOMMON_EXTENSION pdx = (PCOMMON_EXTENSION) fido->DeviceExtension; if(pdx->Flag == EDO_EXTENSION) { status = STATUS_SUCCESS; Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } else { //对Fido的操作...} return STATUS_SUCCESS; } 我觉得以上代码够简化了,在application中只调用CreateFile和CloseFile,还是那问题。头疼。 :( :( |
|
地板#
发布于:2003-04-09 10:51
已经调用
总之,IoCompleteRequest时IRP的状态和分派函数返回的状态都是STATUS_SUCCESS [编辑 - 4/9/03 by daor] |
|
地下室#
发布于:2003-04-09 09:37
ioctl也已经完成
更奇怪的现象是,我只CreateFile,CloseHandle,并且在IRP_MJ_CREATE和IRP_MJ_CLOSE的分派例程中直接以STATUS_SUCCESS将IRP complete,居然还是同样的错误!!IRP_MJ_CLOSE还是没有到达我的驱动程序,就page fault了!真是太神奇了! 以前是正常的,可不知道什么时候突然出现这错误,拿到别的机器上试,还是这错误。重新安装了ddk和ds,还是这错误 没道理啊。。。。。。 |
|
5楼#
发布于:2003-04-09 09:01
全都已complete。
事实上对这个device object的操作的IRP只有IRP_MJ_CREATE、一个IOCTL、IRP_MJ_CLOSE,并且都是在本层complete,不会传往“下一层”(因为这是一个特殊的DO,是在过滤驱动里专门用来与Application打交道的设备对象),我用softice跟踪了所有对它的IRP,已确保全部返回。 |
|