daor
驱动牛犊
驱动牛犊
  • 注册日期2001-05-16
  • 最后登录2018-04-15
  • 粉丝0
  • 关注0
  • 积分-25分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:1179回复:8

非典型性page fault,令人喷血的故障!救命!

楼主#
更多 发布于:2003-04-08 16:41
我创建了一个带有DeviceName的Device Object,并且为之创建了Symbol Link。
  
在用户态可以使用CreateFile打开该设备,并且可以正常进行所有操作,但偏偏在CloseHandle时,系统必page fault。用softice在IRP_MJ_CLOSE的Dispatch Function设断点,居然拦截不住,因为该fault是在系统调用Dispatch之前出现。
    
原来是没问题的,但不知道什么时候出这鬼样,我还从来没碰到过。有经验的战友指点一下谢谢!

[编辑 -  4/8/03 by  daor]
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
沙发#
发布于:2003-04-08 18:08
有未Complete的Irp?
daor
驱动牛犊
驱动牛犊
  • 注册日期2001-05-16
  • 最后登录2018-04-15
  • 粉丝0
  • 关注0
  • 积分-25分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-04-09 09:01
全都已complete。
  事实上对这个device object的操作的IRP只有IRP_MJ_CREATE、一个IOCTL、IRP_MJ_CLOSE,并且都是在本层complete,不会传往“下一层”(因为这是一个特殊的DO,是在过滤驱动里专门用来与Application打交道的设备对象),我用softice跟踪了所有对它的IRP,已确保全部返回。
swf2003
驱动中牛
驱动中牛
  • 注册日期2003-02-13
  • 最后登录2011-10-28
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-04-09 09:16
会不会是 IOCTL 没有正常完成 ?
你的认可是对我最大的鼓励!
daor
驱动牛犊
驱动牛犊
  • 注册日期2001-05-16
  • 最后登录2018-04-15
  • 粉丝0
  • 关注0
  • 积分-25分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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,还是这错误
没道理啊。。。。。。
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
5楼#
发布于:2003-04-09 10:24
ioctl也已经完成
更奇怪的现象是,我只CreateFile,CloseHandle,并且在IRP_MJ_CREATE和IRP_MJ_CLOSE的分派例程中直接以STATUS_SUCCESS将IRP complete,居然还是同样的错误!!IRP_MJ_CLOSE还是没有到达我的驱动程序,就page fault了!真是太神奇了!
以前是正常的,可不知道什么时候突然出现这错误,拿到别的机器上试,还是这错误。重新安装了ddk和ds,还是这错误
没道理啊。。。。。。

直接返回STATUS_SUCCESS就是结束了IRP吗?你没有调用IoCompleteRequest?
daor
驱动牛犊
驱动牛犊
  • 注册日期2001-05-16
  • 最后登录2018-04-15
  • 粉丝0
  • 关注0
  • 积分-25分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-04-09 10:51
已经调用
总之,IoCompleteRequest时IRP的状态和分派函数返回的状态都是STATUS_SUCCESS

[编辑 -  4/9/03 by  daor]
daor
驱动牛犊
驱动牛犊
  • 注册日期2001-05-16
  • 最后登录2018-04-15
  • 粉丝0
  • 关注0
  • 积分-25分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
7楼#
发布于: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,还是那问题。头疼。
      :( :(
daor
驱动牛犊
驱动牛犊
  • 注册日期2001-05-16
  • 最后登录2018-04-15
  • 粉丝0
  • 关注0
  • 积分-25分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
8楼#
发布于: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]
游客

返回顶部