内存泄漏 - DRIVER_VERIFIER_DETECTED_VIOLATION (C4): 0x62

调试内存泄漏 - DRIVER_VERIFIER_DETECTED_VIOLATION (C4): 0x62

此主题尚未评级 评价此主题

当驱动程序上载而没有首先释放其所有池分配时,驱动程序验证程序生成 Bug Check 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION,并具有 0x62 的参数值 1。未释放的内存分配(也称为内存泄漏)是操作系统性能降低的一个常见原因。这些分配会使系统池成为碎片,最终导致系统崩溃。

当你将内核调试程序连接到运行驱动程序验证程序的测试计算机时,如果驱动程序验证程序检测到冲突,Windows 会进入调试程序并显示关于错误的简短描述。

在驱动程序卸载时调试内存泄漏

使用 !analyze 来显示有关调试检查的信息

在进行任何错误检查时,一旦你可以控制调试程序,第一步最好是运行 !analyze -v 命令。

kd> !analyze -v
Connected to Windows 8 9600 x86 compatible target
Loading Kernel Symbols
.................................................................................
Loading User Symbols
.......................
Loading unloaded module list
........
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
A device driver attempting to corrupt the system has been caught.  This is
because the driver was specified in the registry as being suspect (by the
administrator) and the kernel has enabled substantial checking of this driver.
If the driver attempts to corrupt the system, bugchecks 0xC4, 0xC1 and 0xA will
be among the most commonly seen crashes.
Arguments:
Arg1: 00000062, A driver has forgotten to free its pool allocations prior to unloading.
Arg2: 9707712c, name of the driver having the issue.
Arg3: 9c1faf70, verifier internal structure with driver information.
Arg4: 00000003, total # of (paged+nonpaged) allocations that weren't freed.
	Type !verifier 3 drivername.sys for info on the allocations
	that were leaked that caused the bugcheck.

具有 0x62 的参数值 1 (Arg1) 的Bug Check 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION 描述如下:

DRIVER_VERIFIER_DETECTED_VIOLATION (C4)  
Arg1 Arg2 Arg3 Arg4 原因 驱动程序验证程序标志
0x62 驱动程序的名称。 Reserved 未释放的分配总数,包括分页和未分页的池。 驱动程序在上载而没有首先释放其池分配。 在 Windows 8.1 中,如果驱动程序卸载而不首先释放它已使用 IoAllocateWorkItem 分配的任何工作项目 (IO_WORKITEM),也会发生此调试检查。此有此参数的错误检查仅在池跟踪选项激活时发生。 指定池跟踪 (verifier /flags 0x8)池跟踪选项将启用,并带有标准标志 (verifier /standard )。

 

使用 !verifier 3 扩展命令查找有关池分配的信息

对于此特定错误检查,在参数 4 (Arg4) 中提供的信息最重要。Arg4 显示未释放的分配数。!analyze 命令的输出还显示 !verifier 调试程序扩展命令,可以用来显示这些分配的内容。 下例显示了 !verifier 3 MyDriver.sys 命令的完整输出:

kd> !verifier 3 Mydriver.sys

Verify Flags Level 0x000209bb

  STANDARD FLAGS:
    [X] (0x00000000) Automatic Checks
    [X] (0x00000001) Special pool
    [X] (0x00000002) Force IRQL checking
    [X] (0x00000008) Pool tracking
    [X] (0x00000010) I/O verification
    [X] (0x00000020) Deadlock detection
    [X] (0x00000080) DMA checking
    [X] (0x00000100) Security checks
    [X] (0x00000800) Miscellaneous checks
    [X] (0x00020000) DDI compliance checking

  ADDITIONAL FLAGS:
    [ ] (0x00000004) Randomized low resources simulation
    [ ] (0x00000200) Force pending I/O requests
    [ ] (0x00000400) IRP logging
    [ ] (0x00002000) Invariant MDL checking for stack
    [ ] (0x00004000) Invariant MDL checking for driver
    [ ] (0x00008000) Power framework delay fuzzing
    [ ] (0x00040000) Systematic low resources simulation
    [ ] (0x00080000) DDI compliance checking (additional)
    [ ] (0x00200000) NDIS/WIFI verification
    [ ] (0x00800000) Kernel synchronization delay fuzzing
    [ ] (0x01000000) VM switch verification

    [X] Indicates flag is enabled


Summary of All Verifier Statistics

  RaiseIrqls           0x0
  AcquireSpinLocks     0x0
  Synch Executions     0x0
  Trims                0x0

  Pool Allocations Attempted             0x2db1a
  Pool Allocations Succeeded             0x2db1a
  Pool Allocations Succeeded SpecialPool 0x2db1a
  Pool Allocations With NO TAG           0x0
  Pool Allocations Failed                0x0

  Current paged pool allocations         0x0 for 00000000 bytes
  Peak paged pool allocations            0x0 for 00000000 bytes
  Current nonpaged pool allocations      0x3 for 00001058 bytes
  Peak nonpaged pool allocations         0x13 for 0004A4A0 bytes

Driver Verification List
------------------------

  MODULE: 0x84226b28 MyDriver.sys (Loaded)

    Pool Allocation Statistics: ( NonPagedPool / PagedPool )

      Current Pool Allocations: ( 0x00000003 / 0x00000000 )
      Current Pool Bytes:       ( 0x00001058 / 0x00000000 )
      Peak Pool Allocations:    ( 0x00000013 / 0x00000000 )
      Peak Pool Bytes:          ( 0x0004A4A0 / 0x00000000 )
      Contiguous Memory Bytes:       0x00000000
      Peak Contiguous Memory Bytes:  0x00000000

    Pool Allocations:

      Address     Length      Tag   Caller    
      ----------  ----------  ----  ----------
      0x982a8fe0  0x00000020  VMdl  0x9a3bf6ac  MyDriver!DeviceControlDispatch
      0x8645a000  0x00001008  mdrv  0x9a3bf687  MyDriver!DeviceControlDispatch
      0x9a836fd0  0x00000030  Vfwi  0x9a3bf6ed  MyDriver!GetNecessaryObjects

在该示例中,驱动程序 MyDriver.sys 有两个内存分配和一个 I/O 工作项目还未正确释放。 每个列表显示当前分配的地址、大小、使用的池标签,以及做出分配请求的驱动程序代码中的地址。 如果为有问题的驱动程序加载了符号,它也将在调用方地址的旁边显示函数的名称。

在显示的标签中,只有一个(用于地址 0x8645a000 的分配)由驱动程序本身 (mdrv) 提供。 当驱动程序验证程序验证的驱动程序调用 IoAllocateMdl时,将使用标签 VMdl。 类似地,当驱动程序验证程序验证的驱动程序使用 IoAllocateWorkItem 请求分配工作项目时,将使用标签 Vfwi

如果你有符号,可以在发生内存分配的源文件中找到

当为驱动程序加载了符号时,如果这些符号包含行号信息,则可以使用 ln CallerAddress 命令来显示进行调用的行。 此输出也将显示进行分配的函数中的偏移。

kd> ln 0x9a3bf6ac  
d:\coding\wdmdrivers\mydriver\handleioctl.c(50)+0x15
(9a3bf660)   MyDriver!DeviceControlDispatch+0x4c   |  (9a3bf6d0)   MyDriver!DeviceControlDispatch

kd> ln 0x9a3bf687  
d:\coding\wdmdrivers\mydriver\handleioctl.c(38)+0x12
(9a3bf660)   MyDriver!DeviceControlDispatch+0x27   |  (9a3bf6d0)   MyDriver!DeviceControlDispatch

kd> ln 0x9a3bf6ed  
d:\coding\wdmdrivers\mydriver\handleioctl.c(72)+0xa
(9a3bf6d0)   MyDriver!GetNecessaryObjects+0x1d   |  (9a3bf71c)   MyDriver!GetNecessaryObjects

检查日志以查看内存分配

当池跟踪启用时,驱动程序验证程序还保留在内核空间中进行的所有内存分配的循环日志。 默认情况下,将保留最新的 65,536 (0x10000) 项分配。当做出新的分配时,将覆盖日志中最旧的分配。 如果在崩溃前刚进行了分配,则有可能获取比上面显示的更多的分配信息,尤其是分配时的线程地址和内核堆栈框架。

通过使用命令 !verifier 0x80 AddressOfPoolAllocation 可以访问此日志。 请注意,这将列出日志中此特定地址的所有分配和释放。要取消或停止日志历史记录的显示,则使用键盘快捷键:对于 WinDbg 使用 Ctrl + Break,对于 KD 使用 Ctrl + C

kd> !verifier 0x80 0x982a8fe0

Log of recent kernel pool Allocate and Free operations:

There are up to 0x10000 entries in the log.

Parsing 0x00010000 log entries, searching for address 0x982a8fe0.


======================================================================
Pool block 982a8fe0, Size 00000020, Thread 9c158bc0
81b250cd nt!IovAllocateMdl+0x3d
8060e41d VerifierExt!IoAllocateMdl_internal_wrapper+0x35
81b29388 nt!VerifierIoAllocateMdl+0x22
9a3bf6ac MyDriver!DeviceControlDispatch+0x4c
9a3bf611 MyDriver!NonPNPIRPDispatch0x51
9a3bf05a MyDriver!AllIRPDispatch+0x1a
80611710 VerifierExt!xdv_IRP_MJ_DEVICE_CONTROL_wrapper+0xd0
81b3b635 nt!ViGenericDispatchHandler+0x2d
81b3b784 nt!ViGenericDeviceControl+0x18
81b24b4d nt!IovCallDriver+0x2cc
81703772 nt!IofCallDriver+0x62
8191165e nt!IopSynchronousServiceTail+0x16e
81915518 nt!IopXxxControlFile+0x3e8

kd> !verifier 0x80 0x8645a000

Log of recent kernel pool Allocate and Free operations:

There are up to 0x10000 entries in the log.

Parsing 0x00010000 log entries, searching for address 0x8645a000.


======================================================================
Pool block 8645a000, Size 00001000, Thread 9c158bc0
8060ee4f VerifierExt!ExAllocatePoolWithTagPriority_internal_wrapper+0x5b
81b2619e nt!VerifierExAllocatePoolWithTag+0x24
9a3bf687 MyDriver!DeviceControlDispatch+0x27
9a3bf611 MyDriver!NonPNPIRPDispatch0x51
9a3bf05a MyDriver!AllIRPDispatch+0x1a
80611710 VerifierExt!xdv_IRP_MJ_DEVICE_CONTROL_wrapper+0xd0
81b3b635 nt!ViGenericDispatchHandler+0x2d
81b3b784 nt!ViGenericDeviceControl+0x18
81b24b4d nt!IovCallDriver+0x2cc
81703772 nt!IofCallDriver+0x62
8191165e nt!IopSynchronousServiceTail+0x16e
81915518 nt!IopXxxControlFile+0x3e8
81914516 nt!NtDeviceIoControlFile+0x2a

kd> !verifier 0x80 0x9a836fd0  

Log of recent kernel pool Allocate and Free operations:

There are up to 0x10000 entries in the log.

Parsing 0x00010000 log entries, searching for address 0x9a836fd0.


======================================================================
Pool block 9a836fd0, Size 00000030, Thread 88758740
8151713d nt!IovAllocateWorkItem+0x1b
84a133d9 VerifierExt!IoAllocateWorkItem_internal_wrapper+0x29
8151b3a7 nt!VerifierIoAllocateWorkItem+0x16
9a3bf6ed MyDriver!GetNecessaryObjects+0x1d
9a3bf620 MyDriver!NonPNPIRPDispatch0x51
9a3bf05a MyDriver!AllIRPDispatch+0x1a
84a16710 VerifierExt!xdv_IRP_MJ_DEVICE_CONTROL_wrapper+0xd0
8152d635 nt!ViGenericDispatchHandler+0x2d
8152d784 nt!ViGenericDeviceControl+0x18
81516b4d nt!IovCallDriver+0x2cc
810f5772 nt!IofCallDriver+0x62
8130365e nt!IopSynchronousServiceTail+0x16e
81307518 nt!IopXxxControlFile+0x3e8

修复内存泄露

此驱动程序验证程序错误检查旨在防止驱动程序泄露内核内存。 在每种情况下,正确的修复是识别任何未释放分配对象的现有代码路径,并确保它们正确释放。

静态驱动程序验证程序是一种扫描 Windows 驱动程序源代码的工具,通过模拟各种代码路径的练习来报告可能的问题。 静态驱动程序验证程序是一款在开发时使用的出色实用工具,可帮助识别此类问题。

对于其他可以使用的技术,包括驱动程序验证程序未涉及的方案,请参阅查找内核模式内存泄露


转与 http://msdn.microsoft.com/ZH-cn/library/dn457995.aspx/css

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: driver_verifier_dma_violation是一个Windows操作系统的错误代码,通常发生在设备驱动程序中存在DMA(直接内存访问)错误时。这可能是由于驱动程序中的错误代码或硬件故障引起的。为了解决这个问题,可以尝试更新或卸载驱动程序,或者检查硬件是否正常工作。如果问题仍然存在,建议联系技术支持或专业人员进行进一步的故障排除。 ### 回答2: Driver Verifier DMA Violation是Windows系统的一种蓝屏错误,其原因可能是驱动程序在处理直接内存存取(DMA)时发生了错误或难以管理。 DMA是一种用于在集成电路之间传输数据的技术,它可以比处理器更快地进行数据传输。然而,在操作系统中,驱动程序需要负责管理DMA过程。如果驱动程序出现问题,可能会导致数据传输错误或内存访问冲突。这就是Driver Verifier DMA Violation错误的可能原因之一。 在Windows系统中,可以使用驱动程序验证器(Driver Verifier)来检查驱动程序是否存在错误。如果出现DMA Violation错误,驱动程序验证器将停止该驱动程序并向用户显示错误信息。用户可以尝试更新驱动程序或卸载有问题的驱动程序来解决此错误。 另一种可能导致此错误的情况是硬件故障。由于DMA涉及直接内存存取,因此如果硬件存在问题,例如损坏的内存或I/O设备,也可能导致DMA Violation错误。用户可以尝试使用Windows系统自带的故障排除工具来检测硬件问题,或者联系厂商进行更进一步的检测和修复。 总之,如果您在使用Windows操作系统时遇到Driver Verifier DMA Violation错误,需要及时采取措施,例如更新驱动程序或诊断硬件问题。在处理此错误时,如果需要更多帮助和支持,请联系Windows技术支持团队。 ### 回答3: driver_verifier_dma_violation是Windows操作系统中的一个错误代码,通常是由于驱动程序的内存泄漏或错误使用Direct Memory Access(DMA)操作引起的。DMA是一种硬件技术,允许设备直接访问主板的内存,从而提高数据传输速度。当设备驱动程序使用DMA操作时,它需要遵循一些规则以确保正确的内存访问和释放,否则就会导致driver_verifier_dma_violation错误。 常见的导致DMA错误的原因包括: 1.驱动程序过时或不兼容。驱动程序应该是最新版本,并且与操作系统兼容。 2.设备驱动程序没有正确配置DMA操作。要执行DMA操作,必须正确配置DMA通道,并使用正确的缓冲区大小。 3.内存泄漏。如果驱动程序没有适当地释放内存,那么可以导致DMA错误。 如果发现driver_verifier_dma_violation错误,可以采取以下步骤: 1.更新驱动程序。确定驱动程序是否过时,如果是,则需要更新。 2.使用设备管理器检查设备。用设备管理器检查设备是否正常工作,是否有任何出错或警告信息。 3.检查系统日志。检查系统事件日志是否包含有关DMA错误的信息和详细信息。 4.运行系统文件检查器。使用系统文件检查器扫描系统文件是否有损坏或缺失。 5.检查硬件。检查硬件是否与操作系统兼容,是否需要维修或更换。 在进行这些步骤之后,如果driver_verifier_dma_violation错误仍然存在,则可能需要进行更深入的故障排除,或者寻求专业技术支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值