Yes, they are used. It’s a Debug build, so the optimizer isn’t doing this.
It’s a classic Heisenbug, if you debug it, it stops misbehaving. The
assembly that Gary provided is exactly what’s showing up the debugger.
It’s *NOT GETTING EXECUTED* as it was emitted.
From the COD:
; 356 : tAtaIdentifyData ident = { 0};
0003f 66 c7 85 d8 fd
ff ff 00 00 mov WORD PTR _ident$[ebp], 0
00048 b9 7f 00 00 00 mov ecx, 127 ; 0000007fH
0004d 33 c0 xor eax, eax
0004f 8d bd da fd ff
ff lea edi, DWORD PTR _ident$[ebp+2]
00055 f3 ab rep stosd
00057 66 ab stosw
; 357 : tAtaStdParameters ataParms = { 0};
00059 c7 85 a8 fd ff
ff 00 00 00 00 mov DWORD PTR _ataParms$[ebp], 0
00063 33 c0 xor eax, eax
00065 89 85 ac fd ff
ff mov DWORD PTR _ataParms$[ebp+4], eax
0006b 89 85 b0 fd ff
ff mov DWORD PTR _ataParms$[ebp+8], eax
00071 89 85 b4 fd ff
ff mov DWORD PTR _ataParms$[ebp+12], eax
00077 89 85 b8 fd ff
ff mov DWORD PTR _ataParms$[ebp+16], eax
0007d 89 85 bc fd ff
ff mov DWORD PTR _ataParms$[ebp+20], eax
00083 89 85 c0 fd ff
ff mov DWORD PTR _ataParms$[ebp+24], eax
00089 89 85 c4 fd ff
ff mov DWORD PTR _ataParms$[ebp+28], eax
0008f 89 85 c8 fd ff
ff mov DWORD PTR _ataParms$[ebp+32], eax
00095 89 85 cc fd ff
ff mov DWORD PTR _ataParms$[ebp+36], eax
; 358 : ataParms.Data.pData= &ident;
0009b 8d 85 d8 fd ff
ff lea eax, DWORD PTR _ident$[ebp]
000a1 89 85 a8 fd ff
ff mov DWORD PTR _ataParms$[ebp], eax
; 359 : ataParms.Data.AllocLen = ataParms.Data.DataLen = sizeof(ident);
000a7 c7 85 ac fd ff
ff 00 02 00 00 mov DWORD PTR _ataParms$[ebp+4], 512 ;
00000200H
000b1 8b 85 ac fd ff
ff mov eax, DWORD PTR _ataParms$[ebp+4]
000b7 89 85 b0 fd ff
ff mov DWORD PTR _ataParms$[ebp+8], eax
>>>>>>>>>>>>>>>>>
If we breakpoint here on the call to AtaCmdIdentify(ataParms), the memory
at ebp+4 and ebp+8 are filled with garbage. If we breakpoint on the
pointer assignment before we assign the lengths, then run to the
aforementioned bp on the function call, the length values are correct. It
doesn’t help to move the length assignments before the pointer assignment,
or to split them. Is it possible that we’ve found a bug in the CPU
instruction decode that is timing sensitive? Seems unlikely, but how else
do you explain a Heisenbug like this?
>>>>>>>>>>>>>>>>>
; 360 :
; 361 : eAtaError idRes = AtaCmdIdentify(ataParms);
000bd 8b f4 mov esi, esp
000bf 8d 85 a8 fd ff
ff lea eax, DWORD PTR _ataParms$[ebp]
000c5 50 push eax
000c6 8b 4d ec mov ecx, DWORD PTR _this$[ebp]
000c9 8b 11 mov edx, DWORD PTR [ecx]
000cb 8b 4d ec mov ecx, DWORD PTR _this$[ebp]
000ce ff 92 ac 00 00
00 call DWORD PTR [edx+172]
000d4 3b f4 cmp esi, esp
000d6 e8 00 00 00 00 call __RTC_CheckEsp
000db 89 85 9c fd ff
ff mov DWORD PTR _idRes$[ebp], eax
As Gary mentioned, this only occurs on Vista, this has never shown up on
any other OS. Gary will have to give you the in-memory disassembly, I
haven’t gotten around to running Vista here. It’s just what I’ve already
provided, just with addresses fixed up (if there are any. I don’t think
there are any.)
Phil
Philip D. Barila
Seagate Technology LLC
(720) 684-1842
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Arlie Davis
Sent: Tuesday, October 17, 2006 5:03 PM
To: “Windows System Software Devs Interest List”
Subject: RE: [ntdev] Vista “forgets” instructions …
Can you provide a little more info on what happens next with V1, V2, V3,
and V4? Are the values actually consumed by any future statements? The
optimizing compiler will eliminate quite a lot of code if there are no
perceivable side effects. It will happily eliminate assignment of simple
integers, and even long sequences of increment operators, etc.
Your statement that this works on XP doesn’t jive with my suspicion about
the optimizer, though. Can you provide any more info? A complete function
listing, in C or asm?
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Gary G. Little
Sent: Tuesday, October 17, 2006 3:22 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Vista “forgets” instructions …
Here’s one that Phil and I both are scratching our heads over …
We have code that looks something like this:
ULONG V1, V2, V3, V4;
V1 = 0;
V2 = V3 = 1;
V4 = 2;
Unchecked, V2 and V3 will never bet set. If you set a breakpoint on V4, V2
and V3 will not be set. If you set a bp on V1, then V2 and V3 will be set.
Now it gets even stranger: the line V2 = V3 = 1 compiles to 3 MOV’s in
assembly.
00BDEF57 mov dword ptr [ebp-254h],200h
00BDEF61 mov eax,dword ptr [ebp-254h]
00BDEF67 mov dword ptr [ebp-250h],eax
[snip]