Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2006-04

protecting dataspace suggestion

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Пётр Косаревский

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).

Reply by email

Peter Vreman
to Пётр Косаревский
you wrote 15 lines
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.

I don't see the use of this for general implementation in fpc. In 90% of the overwrite cases the stack or heap is corrupted and not the datasegment itself. But ofcourse you can create your own error checking units that fit your own situation.

Peter

Reply by email

Пётр Косаревский
Show quoted text 9 lines
>I don't understand the way FPC stores debug information: line info etc. It >seems useful to not lose this information or at least know, that it was >overwritten. >I got some run time errors with no line info (when compiled with -gcl >option), all of them should be "unreproducible", because all of them >appeared in not so small projects. If they could be caused by overwritten >memory, it would be useful to know about it. Debug information is never loaded into memory it is only available on the disk. Peter

It's dubious.

{$R+}
var a,b:integer;
begin
move(a,b,2000);
a:=32000;
b:=32000;
a:=a*b;
end.

I use win32.
This program (16 bit integer) produces very different results with different values of third parameter of move(a,b,*). System crash (OS exception arises), "normal" work (no exception, no messages), and run time errors 201 or 216 with line info (line 7 or 4) (this is the supposed behavior).

Looking at asm source I see, that data segment contains very very much...

Reply by email

Peter Vreman
to Пётр Косаревский
you wrote 30 lines
> >I don't understand the way FPC stores debug information: line info etc. It > >seems useful to not lose this information or at least know, that it was > >overwritten. > >I got some run time errors with no line info (when compiled with -gcl > >option), all of them should be "unreproducible", because all of them > >appeared in not so small projects. If they could be caused by overwritten > >memory, it would be useful to know about it. > Debug information is never loaded into memory it is only available on the disk. > Peter It's dubious. {$R+} var a,b:integer; begin move(a,b,2000); a:=32000; b:=32000; a:=a*b; end. I use win32. This program (16 bit integer) produces very different results with different values of third parameter of move(a,b,*). System crash (OS exception arises), "normal" work (no exception, no messages), and run time errors 201 or 216 with line info (line 7 or 4) (this is the supposed behavior). Looking at asm source I see, that data segment contains very very much...

This is some theoritical example. Real programs should avoid globals as much as possible. They are also not good for threading.

Also in the debugger with some hardware watchpoints in the datasegment you find the culprit very quickly.

Peter

Reply by email