使用 _analysis_assume 函数抑制误判缺陷

你可以向静态驱动程序验证程序 (SDV) 提供有关驱动程序源代码的其他信息,以便在验证期间可以禁止报告虚假缺陷。 当 SDV 报告明显违反规则,但在驱动程序正常运行的情况下,会出现错误缺陷。

若要向 SDV 提供此附加信息,请使用 __analysis_assume 函数。 函数具有以下语法:

__analysis_assume( expression ) 

其中 ,expression 可以是假定计算结果为 true 的任何表达式。

使用此函数时,SDV 假定表达式表示的条件在__analysis_assume函数出现时为 true__analysis_assume函数仅由静态分析工具使用。 编译器忽略函数。

如果使用 __analysis_assume,请务必确定所做假设的有效性。 如果事实证明你的假设是 错误的,无论是现在还是将来,你都可以抑制真正的缺陷。 建议始终向代码添加注释,说明为何使用 __analysis_assume 函数。 如果无法编写假设的原因,请不要抑制缺陷。

每当发现可以安全抑制的错误缺陷时,应根据需要添加 __analysis_assume 函数。

示例

在以下代码示例中,KMDF 规则 RequestCompletedLocal 报告缺陷。 这是一个错误缺陷,因为 SDV 无法正确解释 switch 语句,因此不会进入请求完成的分支。

在此 switch 语句中,有六种可能的情况。 驱动程序定义了六个 IOCTL 代码,因此驱动程序肯定会采用其中一个分支。 如果采用其中一个分支,则请求将成功完成。

VOID
PortIOEvtIoDeviceControl(
      __in WDFQUEUE     Queue,
      __in WDFREQUEST   Request,
      __in size_t       OutputBufferLength,
  __in size_t       InputBufferLength,
  __in ULONG        IoControlCode
     )
 
     PDEVICE_CONTEXT devContext = NULL;
     WDFDEVICE device;

     PAGED_CODE();
 
     device = WdfIoQueueGetDevice(Queue);
 
     devContext = PortIOGetDeviceContext(device);
 
     switch(IoControlCode)
         case IOCTL_GPD_READ_PORT_UCHAR:
         case IOCTL_GPD_READ_PORT_USHORT:
         case IOCTL_GPD_READ_PORT_ULONG:
             PortIOIoctlReadPort(devContext,
                                 Request,
                                 OutputBufferLength,
                                 InputBufferLength,
                                 IoControlCode);
             break;

 
         case IOCTL_GPD_WRITE_PORT_UCHAR:
         case IOCTL_GPD_WRITE_PORT_USHORT:
         case IOCTL_GPD_WRITE_PORT_ULONG:    
             PortIOIoctlWritePort(devContext,
                                  Request,
                                  OutputBufferLength,
                                  InputBufferLength,
                                  IoControlCode);
             break;
 
     }
 
}

若要安全地抑制错误缺陷,请使用 __analysis_assume 函数指定 保证 IoControlCode 为驱动程序定义的 IOCTL 之一。

VOID
PortIOEvtIoDeviceControl(
      __in WDFQUEUE     Queue,
      __in WDFREQUEST   Request,
      __in size_t       OutputBufferLength,
      __in size_t       InputBufferLength,
      __in ULONG        IoControlCode
     )
 
     PDEVICE_CONTEXT devContext = NULL;
     WDFDEVICE device;

     PAGED_CODE();
 
     device = WdfIoQueueGetDevice(Queue);
 
     devContext = PortIOGetDeviceContext(device);

/* Use __analysis_assume to suppress a false defect for the SDV RequestCompletedLocal rule. 
There are only 6 possible IOCTLs for IoControlCode; each case is covered in the switch statement.
*/

 __analysis_assume( IoControlCode == IOCTL_GPD_READ_PORT_UCHAR || \
                       IoControlCode == IOCTL_GPD_READ_PORT_USHORT|| \
                       IoControlCode == IOCTL_GPD_READ_PORT_ULONG || \
                       IoControlCode == IOCTL_GPD_WRITE_PORT_UCHAR|| \
                       IoControlCode == IOCTL_GPD_WRITE_PORT_USHORT|| \
                       IoControlCode == IOCTL_GPD_WRITE_PORT_ULONG);

     switch(IoControlCode)
         case IOCTL_GPD_READ_PORT_UCHAR:
         case IOCTL_GPD_READ_PORT_USHORT:
         case IOCTL_GPD_READ_PORT_ULONG:
             PortIOIoctlReadPort(devContext,
                                 Request,
                                 OutputBufferLength,
                                 InputBufferLength,
                                 IoControlCode);
             break;

 
         case IOCTL_GPD_WRITE_PORT_UCHAR:
         case IOCTL_GPD_WRITE_PORT_USHORT:
         case IOCTL_GPD_WRITE_PORT_ULONG:    
             PortIOIoctlWritePort(devContext,
                                  Request,
                                  OutputBufferLength,
                                  InputBufferLength,
                                  IoControlCode);
             break;
 
     }
 
}

有关如何使用 __analysis_assume 的另一个示例,请参阅 Using __sdv_save_request and __sdv_retrieve_request for Deferred Procedure Calls 中使用的示例代码。 该示例演示如何将 __sdv_save_request__sdv_retrieve_request 用于 DPC (工作项、计时器等) 。 __analysis_assume 函数用于抑制否则可能导致的错误缺陷。