0

While analyzing Windows Kernel crash dumps using WinDBG, I have often faced a problem of WinDBG not able to read some memory location. Recently while analyzing a Kernel crash dump (minidump file), I observed that there were six stack variables (including two parameters), out of those WinDBG successfully dumped the values of four stack variables but it was returning for other two variable. I could not understand this because all the six variables were part of same stack frame.

In addition to that, I noticed that when I tried to dump a global data structure, WinDBG returned me an error indicating "Unable to read memory at Address 0xfffff801139c50d0". I could not understand why WinDBG could not read a variable which had been defined globally in my driver.

I had loaded the symbols properly, including the PDB file of my driver. WinDBG did not give me any symbols related error.

I want to understand the reason for this behavior. Why does WinDBG fail to read the value of local and global variables? Can someone give me an explanation for this behavior?

Arun Kaushal
  • 593
  • 3
  • 16

1 Answers1

1

Assuming you already have access to private symbols, this error is commonly caused by code optimization in the driver, and the PDBs do not have enough information to determine correction location of variables at all times.

Use !lmi <module name>and check if characteristics field has "perf" to determine of code is optimized.

As advised in Debugging Performance Optimized Code The resulting optimization reduces paging (and page faults), and increases spatial locality between code and data. It addresses a key performance bottleneck that would be introduced by poor positioning of the original code. A component that has gone through this optimization may have its code or data block within a function moved to different locations of the binary. In modules that have been optimized by these techniques, the locations of code and data blocks will often be found at memory addresses different than the locations where they would reside after normal compilation and linking. Furthermore, functions may have been split into many non-contiguous blocks, in order that the most commonly-used code paths can be located close to each other on the same pages. Therefore, a function (or any symbol) plus an offset will not necessarily have the same meaning it would have in non-optimized code. The rule of thumb when working with performance-optimized codes is simply that you cannot perform reliable address arithmetic on optimized code.

You need to check the output of dv /V to determine where the debugger is actually looking for locals, and confirm this is correct.

Malcolm McCaffery
  • 2,468
  • 1
  • 22
  • 43
  • I do not see "perf" in characterstics field if I run !lmi . When I execute dv /V, it gives me output in three columns, first two columns contain the register name and the third column has = . For the variables, I am not able to see the values, it prints in first two columns and = < value unavailable> 2: kd> dv /V pDevObj = @rbx @rbx pData = 0xffffc908`c4cced30 – Arun Kaushal Aug 03 '17 at 13:58
  • There are other more complex potential causes, but whatever they are should start with validating output of dv /V or !for_each_frame dv /i /t /V – Malcolm McCaffery Aug 03 '17 at 14:01
  • I tried "!for_each_frame dv /i /t /V", it does not give me stack variable/parameter dump for stack frames other than my modules stack frame. In my module's stack frame, I am getting the same result - for two local variables. – Arun Kaushal Aug 03 '17 at 14:27