Invalid Floating Point Operation
There are two potential problems with the code that we can see.
First of all you do not check the return value of ReadProcessMemory
. That call could fail for a variety of reasons. Since you don't check for errors you have no way of knowing whether or not the function call succeeded. Always check API calls for success. Read the docs on MSDN to find out how to do so. Usually this involves checking the function return value, as is the case here. If the function fails, then the floating point variable may contain uninitialized data and an error may ensue.
The other problem is that datafloat
is being populated by reading bytes from another process. If those bytes do not represent a valid floating point value, then an exception will be raised if you try to operate on that value. Not all bit patterns represent valid floating point values. For instance, you may have hit upon a signaling NaN value. Perhaps you should be comparing with a CompareMem
given that you appear to be reading arbitrary memory in what looks like an effort to reverse engineer some other program. Testing by bitwise comparison will avoid the risk of loading invalid values into floating registers.
Finally, I'm not sure what you mean by testing a floating point value against null
, whatever null
is. Floating point values are not nullable. It is very likely that you have a significant misunderstanding there.
Related videos on Youtube
D3X
Updated on June 14, 2022Comments
-
D3X almost 2 years
I keep getting this error "Invalid Floating Point Operation".
I'm on Delphi 7.
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, TlHelp32, Dialogs, StdCtrls, ExtCtrls, Buttons, ComCtrls; var //global PHandle, cancel, bytes, scantype: integer;
...
procedure Tmain.scanbtnClick(Sender: TObject); var max, address: Integer; floatinput, floatinput1, floatinput2, datafloat: Real; x: cardinal; itm: TListItem; begin floatinput := StrToFloat(Trim(valueinput.Text)); floatinput1 := StrToFloat(Trim(valueinput1.Text)); floatinput2 := StrToFloat(Trim(valueinput2.Text)); if floatinput2 < floatinput1 then begin floatinput1 := floatinput1 + floatinput2; floatinput2 := floatinput1 - floatinput2; floatinput1 := floatinput1 - floatinput2; end; result.Show; x := 0; address := 0; result.resultlist.Clear; repeat Application.ProcessMessages; statusbar1.Panels.Items[1].Text := 'Searching... ' + IntToStr(address * 100 div max) + '% (' + IntToStr(address div bytes) + ' out of ' + IntToStr(max div bytes) + ').'; if ReadprocessMemory(PHandle, Ptr(address), @datafloat, bytes, x) then begin if (x > 0) then begin if scantype = 0 then begin if datafloat = floatinput then //error here begin itm := result.resultlist.Items.Add; itm.Caption := '0x' + IntToHex(address,8); itm.SubItems.Add(FormatFloat('0.0#########', datafloat)); end; end; if scantype = 1 then begin if datafloat > floatinput //also here then begin itm := result.resultlist.Items.Add; itm.Caption := '0x' + IntToHex(address,8); itm.SubItems.Add(FormatFloat('0.0#########', datafloat)); end; end; if scantype = 2 then begin if datafloat < floatinput //here too then begin itm := result.resultlist.Items.Add; itm.Caption := '0x' + IntToHex(address,8); itm.SubItems.Add(FormatFloat('0.0#########', datafloat)); end; end; if scantype = 2 then begin if (dataint <= intinput2) and (dataint >= intinput1) //even here then begin itm := result.resultlist.Items.Add; itm.Caption := '0x' + IntToHex(address,8); itm.SubItems.Add(FormatFloat('0.0#########', datafloat)); end; end; end; end; if x <> 0 then address := address + x else address := address + bytes; until (address >= Max) or (cancel = 1); end;
I even checked on the cpu window, and it happens because its trying to load a floating point value from a pointer that is pointing at a null value.
It's not the ReadMemory, because this little piece of code is on a while loop and it returns several valid values before running into this error.
What should I do?
Thanks in advance.
-
D3X over 8 yearsOkay so i changed my code, and now i only proceed if the result of ReadProcessMemory is true, and then i check if the number of bytes read is > 0, and even though i don't fully understand why, the comparemem routine worked, but what if i want to know if datafloat > floatinput? Shouldn't I be able to compare two real values?
-
D3X over 8 yearsActually.. nope. CompareMem is returning false even when it should return true, when i use normal comparison it returns only the values that it should, but always step in this error after a while..
-
D3X over 8 yearsOkay, i fixed it, your answer was actually really usefull. What i did was declare 'Math' in uses and then check if 'datafloat' is not a NaN by using the IsNan routine, thank you.
-
David Heffernan over 8 yearsCompareMem will work if you use it right. If you want to do other than equality comparison for non-zero, finite values it will work. Using IsNaN is a good option. The whole point is that you are operating on values whose provenance you don't know.