[fpc-devel] protecting dataspace suggestion

Пётр Косаревский ppkk at mail.ru
Mon Apr 17 12:59:36 CEST 2006


Sometimes RTL dataspace, including run time error numbers (may be some debug information), is corrupted because of poor programming. It's a reason for getting strange messages like "Run time error 998" (may be omitting line number information etc).

FPC has implemented e.g. some checks for pointers, so some checks for corrupted RTL dataspace would not be really out of the way.

If I get it right, there is a simple way to check validity of dataspace (e.g. RTL one) using global properties. I suggest three ways. Of course, all of them are for debug purposes and are not for releases.

Also, no error correction is provided, but it is possible (with slightly more complicated algorithm). But it wouldn't help after large memory block is garbaged.

1. (doubles data, little time overhead) (integer as longword)
 property ErrNum: integer read ErrNumR write ErrNumW;
 ...
 var ErrNumMain,ErrNumAux: integer;
 function ErrNumR: integer;
  begin
  if ErrNumAux=ErrNumMain xor $55555555 then
     Result:=ErrNumMain
    else
     Raise Exception.Create('ErrNum data corrupted.');
  end;
 procedure ErrNumW(Value: integer);
  begin
  if ErrNumAuxn=ErrNumMain xor $55555555 then
     begin
     ErrNumMain:=Value;
     ErrNumAux:=Value xor $55555555;
     end
    else
     Raise Exception.Create('ErrNum data corrupted.');
  end;



2. (usually one extra longword, though much time) (integer as longword, no overflow checks)
 property ErrNum: integer read ErrNumR write ErrNumW;
 property Another: integer read AnotherR write AnotherW;
 ...
 var _ErrNum,_Another: integer;
     CheckCode: integer;
 const ErrNumCode:longword  =$12345671;
       AnotherCode:longword =$34567123;
       NullCode:longword =$55555555;
 function ErrNumR: integer;
  begin
  if CheckDataspace() then
     Result:=_ErrNum
    else
     Raise Exception.Create('ErrNum data corrupted.');
  end;
 procedure ErrNumW(Value: integer);
  begin
  if CheckDataspace() then
     begin
     _ErrNum:=Value;
     UpdateDataspace();
     end
    else
     Raise Exception.Create('ErrNum data corrupted.');
  end;

  procedure UpdateDataspace;
   begin
   CheckCode:=(_ErrNum xor ErrNumCode)+(_Another xor AnotherCode)+NullCode;
   end;
  function CheckDataspace: boolean;
   begin
   result:=(CheckCode=( _ErrNum xor ErrNumCode)+(_Another xor AnotherCode)+NullCode );
   end;
The last two procedures can substitute '+' with something else (like 'xor': ((a xor ac) xor (b xor bc)) xor nc) etc... (Of course, no overflow checkings.)


3. Something more complicated.
   Let read/write hide value in some memory area, that is not normally accessible (i.e., causes sharing violation, general protection fault or something). E.g., it can use other process for storing of these values. It seems to be system dependent.




My own comments:
1. it doesn't seem very hard to implement one or another approach, using properties doesn't require much rewriting.
2. first two approaches should detect corruption in about 2^32/(2^32-1) cases quota, which is quite near to 1 (all).



More information about the fpc-devel mailing list