1

我正在尝试通过串行电缆使用 WinDbg 6.2.9200.16384 x64 来调试我正在编写的驱动程序。WinDbg 可以很好地连接到目标机器(Windows 8),当系统启动并加载所有内容时,我可以看到所有的 dbgprint。我可以很好地为我的驱动程序加载符号并可以设置断点,当我的驱动程序遇到这些断点时,系统会按预期停止。这就是事情变得奇怪的地方:当我遇到断点时,我只能在本地窗口和使用“dv”命令时看到我的函数中的一些局部变量。我创建了一个变量来测试:

int myInt = 8;

当我使用 dbgprint 显示 myInt 的值时,它工作正常,我看到它为 8。但是,该变量甚至根本不会出现在本地窗口或使用“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。它告诉我 offset 的值不是我期望的 0x777,而是 0xE061(每次运行代码时都会改变)。当我仔细查看 locals 窗口时(通过 'dv' 和 '?varname' 命令显示相同的信息),我注意到 offset 的位置和 rcb 的位置是完全相同的地址。同样,writeAddr 和 readAddr 也存储在相同的地址。调试器未检测到任何其他变量。

我确信我已经正确加载了符号,源和符号路径设置正确,我已经运行了 '.reload /f' 一百万次,加载驱动程序的符号没有错误。我仍然能够打破并单步执行其他代码行,但当地人没有任何意义。当我进行 dbgprint 时,会显示正确的值,因此这似乎是调试器本身的问题,而不是我的驱动程序的问题。有任何想法吗?

4

2 回答 2

1

<> 如今,编译器已经得到了很大的增强,可以通过优化的性能和其他指标获得更好的优化二进制文件。因此编译器将少量变量存储为局部变量(通过 'dv /v' 命令可见)并将其他变量存储在它们的寄存器中。这就是您在 dv 命令中没有看到变量int myInt的原因。我们可以通过使用'uf binary!functionname'反汇编函数或通过在 Windbg View-> Disassembly 中查看反汇编代码来了解哪些寄存器正在用于变量。

请注意,无论是否优化编译器,驱动程序在性能、内存使用等方面的行为可能略有不同。因此始终建议调试从默认优化编译器生成的编译器,因为这是实时用户使用的编译器设想。

于 2013-07-25T08:54:28.163 回答
1

我解决了这个问题。对于遇到同样事情的其他人:我正在使用免费构建的驱动程序,所以编译器优化了我的很多变量。要修复它,要么编译驱动程序的检查版本,要么添加行

MSC_OPTIMIZATION=/Od /Oi

到您的源文件以禁用免费构建的优化。希望这可以帮助任何有同样问题的人。

于 2013-07-25T21:49:35.923 回答