[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