我正试图通过串行电缆使用WinDbg 6.2.9200.16384 x64来调试我正在编写的驱动程序。WinDbg连接到目标机器(Windows 8)很好,当系统引导和加载所有内容时,我看到了所有的dbgprint。我可以很好地加载驱动程序的符号,并可以设置断点,当我的驱动程序遇到这些断点时,系统会按预期停止。这就是事情变得奇怪的地方:当我遇到断点时,我只能在locals窗口和使用"dv"命令时看到函数中的一些局部变量。我创建了一个要测试的变量:
int myInt = 8;
当我使用dbgprint来显示myInt的值时,它工作得很好,我认为它是8。然而,该变量甚至根本不会出现在locals窗口中或使用"dv"命令。其他变量确实如此,如
ULONG rcb = 0;
我可以在当地人的橱窗里看到它的价值。这些变量是一个接一个地声明的。
这个奇怪问题的另一个症状是这样的。我有一个功能
ULONG someFunction(UINT16 offset) {
ULONG rcb, tempAddr, temp, temp1;
ULONG writeAddr, readAddr;
UINT16 dev;
dev = 15;
...
}
我这样称呼这个函数:
someFunction(0x777);
当我在这个函数中设置断点并使用WinDbg检查变量值时,没有任何意义。首先,它只看到我的8个变量中的4个,只有offset、rcb、writeAddr和readAddr。它告诉我偏移量的值不是我所期望的0x777,而是0xE061(每次运行代码时都会发生变化)。当我仔细查看locals窗口时(相同的信息通过"dv"one_answers"?varname"命令显示),我注意到偏移的位置和rcb的位置是完全相同的地址。同样,writeAddr和readAddr也存储在同一地址。调试器未检测到任何其他变量。
我确信我已经正确加载了符号,源和符号路径设置正确,我已经运行了一百万次".reload/f",在加载驱动程序的符号时没有出错。我仍然能够突破和遍历其他代码行,但本地代码没有任何意义。当我dbgprint时,会显示正确的值,所以这似乎是调试器本身的问题,而不是我的驱动程序的问题。有什么想法吗?
<>如今,编译器已经得到了很大的增强,以获得更好的二进制优化性能和其他指标。因此,编译器将一些变量存储为局部变量(通过"dv/v"命令可见),并将其他变量存储在其寄存器中。这就是您在dv命令中没有看到变量int myInt的原因。通过使用'of binary对函数进行反汇编,我们可以知道哪些寄存器用于变量!functionname"或通过在Windbg View->反汇编中查看反汇编的代码。
请注意,无论是否优化编译器,驱动程序在性能、内存使用等方面的行为都可能略有不同。因此,始终建议调试从默认优化编译器生成的驱动程序,因为这是实时用户场景中使用的驱动程序。
我解决了这个问题。对于其他遇到同样情况的人来说:我使用的是免费构建的驱动程序,所以编译器优化了我的很多变量。要修复它,可以编译一个经过检查的驱动程序版本,或者添加行
MSC_OPTIMIZATION=/Od /Oi
到您的源文件,以禁用免费构建的优化。希望这能帮助到任何有同样问题的人。