Thu Jan 21 17:02:33 2016: Request 80322 was acted upon. Transaction: Correspondence added by TONYC Queue: Win32-API Subject: 'make test' failure - 03_Jim_Shaw.t - invalid unpack type Broken in: 0.72, 0.73 Severity: Important Owner: Nobody Requestors: jdhed...@cpan.org Status: resolved Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=80322 >
On Thu Jan 21 15:49:36 2016, BULKDD wrote: > After having no clue how to fix this, and having some doubts if this > ticket is real, I reproduced it with Win 7+VC 2013. Perhaps something > in EnumChildWindows changed between Win XP and Win7 that stopped > "resetting" the FPU, or the SSE heavy instead of x87, machine code of > VC 2013 wasn't clearing the FPU state the way the older non-SSE code > wouldve, or EnumChildWindows in WinXP used ebp as base pointer and in > Win7 when MS compiled user32.dll, ebp was reused as GPR with only esp > addressing. > > Anyways, what was happening was each fld op in the shellcode callback > was pushing one var onto FPU stack. Eventually the FPU stack which has > 8 elements was filled. x87 Stack Fault (bit 6) exception bit came on > at that point. After that, no further FPU math was possible. NAN was > the result of every op. That resulted in this PP division op failing, > after 8 calls of the W::A::C callback > https://metacpan.org/source/BULKDD/Win32-API-0.82/Callback.pm#L176 > this line in PP was returning NAN even though its "16/4" which cant > possibly be NAN. The NAN in a SVNV after going through SvUV became 0, > so the callback unwound the C stack by 0 bytes instead of 8 as stdcall > requires (EnumChildWindows wants a stdcall func, not cdecl). > Eventually EnumChildWindows poped nonvol register esi from the wrong > location on C stack a couple hundred bytes away from the correct > location of the saved esi register, since every call into the callback > screwed up esp by 8 bytes. The corrupted esi register after > EnumChildWindows returned control to W::A causing a crash in > Win32::API's Call_asm. That sounds like a bug we had in one of the perl BBC reports last year. A module was calling the Time::HiRes Time::NVtime entry point from C with the wrong prototype, mis-balancing the FPU stack, which resulted in a NaN in a unrelated location. I ended up diagnosing it by adding code to the perl run loop to check the FPU stack was empty, and abort with the current location in the perl code when it wasn't. Tony