1

When you debug optimised code, I know that address arithmetic doesn't work correctly:

0:004> u dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x69
u dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x69
dwmcore!CPartitionVerticalBlankScheduler::PresentFrame+0x15:
000007fe`f97420f1 81eca0000000    sub     esp,0A0h
000007fe`f97420f7 33db            xor     ebx,ebx
000007fe`f97420f9 458ad1          mov     r10b,r9b
000007fe`f97420fc 418be8          mov     ebp,r8d
000007fe`f97420ff 488bf2          mov     rsi,rdx
000007fe`f9742102 488bf9          mov     rdi,rcx
000007fe`f9742105 389a10010000    cmp     byte ptr [rdx+110h],bl
000007fe`f974210b 740c            je      dwmcore!CPartitionVerticalBlankScheduler::PresentFrame+0x26d (000007fe`f9742119)

Offset 0x69 from dwmcore!CPartitionVerticalBlankScheduler::WaitForWork is actually in another function. So how does windbg manage to correctly apply the dwmcore!CPartitionVerticalBlankScheduler::PresentFrame symbol to an offset 0x54 from dwmcore!CPartitionVerticalBlankScheduler::WaitForWork when the pdb clearly must contain another address for the symbol that is at a much greater offset than 0x54 for the original unoptimised code?

When you disassemble the WaitForWork function, it somehow manages to resolve the original offsets such that you can see what dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x69 really means

uf dwmcore!CPartitionVerticalBlankScheduler::WaitForWork
dwmcore!CPartitionVerticalBlankScheduler::WaitForWork:
000007fe`f9742088 48895c2408      mov     qword ptr [rsp+8],rbx
000007fe`f974208d 57              push    rdi
000007fe`f974208e 4883ec20        sub     rsp,20h
000007fe`f9742092 833d6ba50d0000  cmp     dword ptr [dwmcore!Microsoft_Windows_Dwm_Core_Provider_Context+0x24 (000007fe`f981c604)],0
000007fe`f9742099 488bd9          mov     rbx,rcx
000007fe`f974209c 48bf0100000000000080 mov rdi,8000000000000001h
000007fe`f97420a6 0f856bfc0600    jne     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x20 (000007fe`f97b1d17)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x5c:
000007fe`f97420ac 488b4b18        mov     rcx,qword ptr [rbx+18h]
000007fe`f97420b0 488d5370        lea     rdx,[rbx+70h]
000007fe`f97420b4 e8b7f1ffff      call    dwmcore!CPartitionManager::GetWork (000007fe`f9741270)
000007fe`f97420b9 833d44a50d0000  cmp     dword ptr [dwmcore!Microsoft_Windows_Dwm_Core_Provider_Context+0x24 (000007fe`f981c604)],0
000007fe`f97420c0 8bd8            mov     ebx,eax
000007fe`f97420c2 0f859dfc0600    jne     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x74 (000007fe`f97b1d65)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0xb4:
000007fe`f97420c8 8bc3            mov     eax,ebx
000007fe`f97420ca 488b5c2430      mov     rbx,qword ptr [rsp+30h]
000007fe`f97420cf 4883c420        add     rsp,20h
000007fe`f97420d3 5f              pop     rdi
000007fe`f97420d4 c3              ret

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x20:
000007fe`f97b1d17 8a05eba80600    mov     al,byte ptr [dwmcore!Microsoft_Windows_Dwm_Core_Provider_Context+0x28 (000007fe`f981c608)]
000007fe`f97b1d1d 3c04            cmp     al,4
000007fe`f97b1d1f 7308            jae     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x2e (000007fe`f97b1d29)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x2a:
000007fe`f97b1d21 84c0            test    al,al
000007fe`f97b1d23 0f858303f9ff    jne     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x5c (000007fe`f97420ac)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x2e:
000007fe`f97b1d29 48853dc0a80600  test    qword ptr [dwmcore!Microsoft_Windows_Dwm_Core_Provider_Context+0x10 (000007fe`f981c5f0)],rdi
000007fe`f97b1d30 0f847603f9ff    je      dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x5c (000007fe`f97420ac)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x37:
000007fe`f97b1d36 488b0dbba80600  mov     rcx,qword ptr [dwmcore!Microsoft_Windows_Dwm_Core_Provider_Context+0x18 (000007fe`f981c5f8)]
000007fe`f97b1d3d 488bc1          mov     rax,rcx
000007fe`f97b1d40 4823c7          and     rax,rdi
000007fe`f97b1d43 483bc1          cmp     rax,rcx
000007fe`f97b1d46 0f856003f9ff    jne     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x5c (000007fe`f97420ac)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x49:
000007fe`f97b1d4c 488b0d4db10600  mov     rcx,qword ptr [dwmcore!Microsoft_Windows_Dwm_CoreHandle (000007fe`f981cea0)]
000007fe`f97b1d53 488d15e6fd0500  lea     rdx,[dwmcore!EVTDESC_SCHEDULE_WFW_Start (000007fe`f9811b40)]
000007fe`f97b1d5a e871f30100      call    dwmcore!TemplateEventDescriptor (000007fe`f97d10d0)
000007fe`f97b1d5f 90              nop
000007fe`f97b1d60 e94703f9ff      jmp     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x5c (000007fe`f97420ac)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x74:
000007fe`f97b1d65 8a0d9da80600    mov     cl,byte ptr [dwmcore!Microsoft_Windows_Dwm_Core_Provider_Context+0x28 (000007fe`f981c608)]
000007fe`f97b1d6b 80f904          cmp     cl,4
000007fe`f97b1d6e 7308            jae     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x83 (000007fe`f97b1d78)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x7f:
000007fe`f97b1d70 84c9            test    cl,cl
000007fe`f97b1d72 0f855003f9ff    jne     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0xb4 (000007fe`f97420c8)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x83:
000007fe`f97b1d78 48853d71a80600  test    qword ptr [dwmcore!Microsoft_Windows_Dwm_Core_Provider_Context+0x10 (000007fe`f981c5f0)],rdi
000007fe`f97b1d7f 0f844303f9ff    je      dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0xb4 (000007fe`f97420c8)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x8c:
000007fe`f97b1d85 488b0d6ca80600  mov     rcx,qword ptr [dwmcore!Microsoft_Windows_Dwm_Core_Provider_Context+0x18 (000007fe`f981c5f8)]
000007fe`f97b1d8c 488bc1          mov     rax,rcx
000007fe`f97b1d8f 4823c7          and     rax,rdi
000007fe`f97b1d92 483bc1          cmp     rax,rcx
000007fe`f97b1d95 0f852d03f9ff    jne     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0xb4 (000007fe`f97420c8)

dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0x9e:
000007fe`f97b1d9b 488b0dfeb00600  mov     rcx,qword ptr [dwmcore!Microsoft_Windows_Dwm_CoreHandle (000007fe`f981cea0)]
000007fe`f97b1da2 488d15a7fd0500  lea     rdx,[dwmcore!EVTDESC_SCHEDULE_WFW_Stop (000007fe`f9811b50)]
000007fe`f97b1da9 448bc3          mov     r8d,ebx
000007fe`f97b1dac e8e3240200      call    dwmcore!Template_q (000007fe`f97d4294)
000007fe`f97b1db1 90              nop
000007fe`f97b1db2 e91103f9ff      jmp     dwmcore!CPartitionVerticalBlankScheduler::WaitForWork+0xb4 (000007fe`f97420c8)

You can see that offset 0x69 from WaitForWork really means offset 0x31. So why does windbg just not detect that it is optimised and recalculate offsets to avoid the confusion and just say 0x31 in the stack trace as the symbol name, it clearly has the ability to do so. Furthermore, how does it even get the original symbol (symbol offset) for the address right (which was my first question). Does it compare instruction bytes? I found this link but it only tells you what happens, which I already know, and not how.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.