Classic Object Pascal for free
I'm just experiencing a strange crash (...floating point exception) when using the Now function...
It crashes on a... 'fild' ...as seen in the CPU panel.
What is odd... is that it works perfectly elsewhere in the program - and there is nothing unusual that I can see ... ie: that I might have done, ... that would seem to be the cause of it.
DTEnd : tDateTime;
& in the code ...
DTEnd := Now; <------ .....and it crashes here.
(and the code is about as basic as you can get .. eh?)
Yet this is a definition in a unit I use all the time ... and I have never seen it crash on this before.
It's in a routine that is called at the end of every program & calculates & displays the elapsed runtime.
And .. everything calls it and .. until now .. it has worked just fine.
Of course, it suggests I have done something (somewhere) to cause this - but I really cannot think of what it might be...
I realise there are 2 places where tDateTime is defined in VP (ie: System & Dos) .. and I have tried
(in desperation), to ensure it is using System, thus .... (in case the Dos defn was overriding .. somehow)
DTEnd : System.tDateTime;
But .. that didn't help either
I have tried rebooting the system etc but .. also .. no help.
NB: I did get a (genuine) floating point error in other code earlier, when inadvertently doubling a Comp field which already contained the maximum value (ie: 2**63). Of course, this was corrected when found ..but whether or why this should have any effect completely baffles me. ie: Even if the error was retained/logged somewhere, it would surely be cleared by a reboot & recompile ... you'd think!
Surely the onboard FPU can't have been damaged somehow .. can it..?
Does anyone have any ideas or suggestions please?
The only thing that comes to mind if the abend occurs on a FILD is the a floating point stack overflow, but that's unlikely, unless you actually use BASM floating point code yourself. What does the FPU window show as being on the FPU stack?
Thanks for the reply.
It occurs in VP code somewhere (part of the system function behind "Now"). So I don't know the answer about which floating point type.
Also... I can only "see" the VP CPU panel .. so I'm not sure where (or if) I can see the FPU stack you mentioned. Certainly the general stack is visible .. but I imagine that doesn't help .. or does it?
I have single-stepped the VP assembler code (via the debugger) and it's (now) clear that the instruction is executed more than once - and it doesn't initially give a problem. So that would seem to reinforce your idea of a stack problem .. wouldn't it?
I also re-compiled & ran another simple program which uses my identical routine .. and it continues to work just fine. Which suggests (again) it's something I'm doing in this program .. somehow.
NB: I had the general stack size set to 512k .. I reduced it to 256k .. (in case that would 'free' more for the FPU) ....but that didn't help either.
BTW .. this is all under XP+sp3 .. on a C2D .. with 4GiB ram. ie: You'd think/hope there would be more than enough memory available...
Is there a way I can get &/or influence the stack size for the FPU ... I have no background in this - so please .. be gentle with me :-)))
Aha! .. I didn't realise there was a panel to view the FPU etc ...it helps to RTFM eh? :-))
So .. here is the debugger screen output showing the exception etc ... NB: It will be necessary to cut'n'paste this into Notepad (or similar) to view it correctly...
║ cs:004094AF►DB45F0 fild DWord Ptr [ebp-10h] ▲eax 0000-0118│c=0║
║ cs:004094B2 8B4508 mov eax,[ebp+8] ■ebx 7FFD-6000│z=0║
║ cs:004094B5 DD18 fstp QWord Ptr [eax] ▒ecx 0000-0190│s=0║
║ cs:004094B7 B301 mov bl,1 ▒edx 0000-000C│o=0║
║ cs:004094B9 8AC3 mov al,bl ▒esi 0000-A252│p=0║
║ cs:004094BB 5F pop edi ▒edi 0000-07DC│a=0║
║ cs:004094BC 5E pop esi ▒ebp 0012-FB08│i=1║
║ cs:004094BD 5B pop ebx ▒esp 0012-FAEC│d=0║
║ cs:004094BE 8BE5 mov esp,ebp ▒efl 0001-0302│ ║
║ cs:004094C0 5D pop ebp ▒eip 0040-94AF│ ║
║ cs:004094C1 C21000 ret 10h ▒ cs .....001B│ ║
║ cs:004094C4 55 push ebp ▒ ds .....0023│ ║
║ cs:004094C5 8BEC mov ebp,esp ▒ es .....0023│ ║
║ cs:004094C7 83EC08 sub esp,8 ▒ ss .....0023│ ║
║ cs:004094CA 0FB74510 movzx eax,Word Ptr [ebp+10h] ▼ fs .....003B│ ║
║ ds:10000 41 00 4C 00 4C 00 55 00 A L L U │ ss:0012FAFC 0040B61B║
║ ds:10008 53 00 45 00 52 00 53 00 S E R S │ ss:0012FAF8 0000A252║
║ ds:10010 50 00 52 00 4F 00 46 00 P R O F │ ss:0012FAF4 7FFD6000║
║ ds:10018 49 00 4C 00 45 00 3D 00 I L E = │ ss:0012FAF0 002F0020║
║ ds:10020 45 00 3A 00 5C 00 44 00 E : \ D │ ss:0012FAEC►002F0020║
░░░░░░░░░░░░░░░░░░░░░░╔═[■]═══════════ Error ════════════════╗░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░║ Exception ║░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░║ XCPT_FLOAT_INVALID_OPERATION ║░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░║ (C0000090) at 00401969, TID = 03BC ║░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░║ Ok ▄ ║░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░║ ▀▀▀▀▀▀▀▀ ║░░░░░░░░░░░░░░░░░░
┌──────────────────────────────────── Ncp ───────────────────────┬──────┬1─────┐
│Empty ST(7) 0000 0000 0000 8000 403D│ im=0 │ ie=1 │
│Empty ST(6) 0000 0000 2000 BEBC 4019│ dm=1 │ de=0 │
│Empty ST(5) 0020 002F 0020 002F 0050│ zm=0 │ ze=0 │
│Empty ST(4) 0020 002F 0020 002F 0020│ om=0 │ oe=0 │
│Empty ST(3) 0020 002F 0020 002F 0020│ um=1 │ ue=0 │
│Empty ST(2) 0020 002F 0020 002F 0020│ pm=1 │ pe=1 │
│Empty ST(1) 0020 002F 0020 002F 0020│ pc=3 │ sf=0 │
│Valid ST(0) 9.22337203685477581e+18 0000 0000 0000 8000 403E│ rc=0 │ es=1 │
│ │ ic=1 │ cc=0 │
├────────────────────────────────────────────────────────────────┤ │ st=7 │
│IPTR = 001B:00401969 (fistp QWord Ptr [411F8Ch]) │ │ │
│OPTR = 0023:00411F8C ├──────┼──────┤
│OPCODE = 73D │ 1372 │ B8A1 │
ST(0) contains 2**63-1, which is kind of suspicious...
Do you know where you are in the RTL - now on holiday at the other end of Europe, will be able to help more next week when I'm home.
It must(?) be your own code, the fild-mov-fstp code does not seem to appear anywhere in the VP RTL source code - turns out I had the VP install on my laptop
put an asm fwait; end; in code just before the now() call, and see if the exception happens there instead of the now.
Genius! That solved it 100% .... No exception now... Many Thanks!
But .. pls tell us all why it's necessary.
NB: It's true that my mickey-mouse program was using the FPU as well (.. uses comp fields) ... so .. should I have put an fwait in *it*... somewhere? ... I admit I don't understand why it's necessary....
It was not meant as a solution, but as a diagnostic aid. IOW if the exception location shifted the problem wasn't in the NOW but in whatever floating point code was executed before NOW.
If the problem suddenly goes away probably hints that there is a randomness to the problem. Might mean that you operate on an uninitialized FP value somewhere, and if the problem happens or not depends on what is in the memory location of the uninitialized FP. Which can change when you make changes to the program.
Yes .. I spoke too soon <sigh> ....
It did indeed *appear* to have solved the problem, as it then ran perfectly.
And I was ...overjoyed! ...since it had been driving me nuts! :-))
But .. (isn't there always a.. but..) when I ran it again the following day,
the problem was .. back again.... Grrrrr.
After a lot more care, checking things v-e-r-y v-e-r-y slowly, it became
apparent that I did still have a bug in the code which caused the comp field
into an error .. again when it reached 2^63.
In short - mea culpa - I had thought that a comp field held 2^63 but (of
course) it's 1 less than that 2^63 - 1 ... ouch!
ie: I was still (incorrectly) trying to double it ... when it couldn't
hold it !! So .. mea culpa! ...My apologies to all.
As to why it worked when I added in the 'fwait' .... I have no idea at all.
At that point, the same (incorrect) code was being executed .. so .. it
*should* have continued to fail with the exception... but .. didn't!
So .. thanks for all the help ...
If it's any compensation .. I *have* learned something out of all this ...! :-))