HP3000-L Archives

April 1997, Week 2

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Stan Sieler <[log in to unmask]>
Reply To:
Stan Sieler <[log in to unmask]>
Date:
Tue, 8 Apr 1997 11:53:27 -0700
Content-Type:
text/plain
Parts/Attachments:
text/plain (273 lines)
Brian said:
...
> > Also, XCODETRAP/XARITRAP/XSYSTRAP and the POSIX signal handlers
> > are also forms of error handling and recovery.
>
> I suspect it is in this area that my interest lies. I had a brief
...
> Being able to treat a divide by zero or de-reference of a null pointer
> with the same mechanism as a user thrown exception would be nice.


Pascal:

   ...code A...
   try
      begin
      ...code B...
      end
   recover
      begin
      ...code C...
      end;
   ...code D...

In the above, if a trap occurs in code block B, an implicit "goto"
(sort of) is done, sending you to the start of the code in the
"recover" block (code block C), with a magic variable "escapecode"
setup with a 32-bit error value (to tell you what happened).

What's a trap.  Some or all of:

   - Pascal range violation (e.g., index out of range)

   - divide by 0

   - integer overflow

   - illegal pointer

Here's example code that "safely" tries to load a 32-bit integer
from a pointer, without aborting if the pointer is bad in some way
(and there are at least 3 ways it can be bad!):

NOTE: try/recover isn't perfect.  See at least *commentary* note #2-7 in:
http://www.allegro.com/papers/htpp.html  (there are two "#2-7" strings
on the page)

--------------------------------------cut here-------------------------

{load32.source 97/04/08}

$standard_level 'os_features'$
$type_coercion 'representation'$

$set 'USE2 = false'$          {if TRUE, makes load_from_iptr32}
                              {         handle 2-byte aligned }
                              {         addresses as well as  }
                              {         4-byte aligned ones.  }

program m;

type
   i32_a2         = $alignment 2$ integer;

$if 'USE2'$
   iptr32_type    = ^ i32_a2;
$else$
   iptr32_type    = ^ integer;
$endif$

   str32          = string [32];
   str256         = string [256];

{---------------------- intrinsics --------------------}

Function dascii               : shortint;    intrinsic;
Procedure hperrmsg;                          intrinsic;
Procedure print;                             intrinsic;

{---------------------forward routines----------------}

Function hex32 (n : integer) : str32;
   forward;

Function num32 (n : integer) : str32;
   forward;

Procedure ws (s : str256);
   forward;

{********************************************************}
procedure load_from_iptr32 (
              var status      : integer;
                  ptr         : iptr32_type;
              var result      : integer);

      {Returns status = 0 if no error, otherwise}
      {status has an error code.                }

   begin

   status := 0;      {assume no error}

   try
      begin
      result := ptr^;

         {Note: if ptr is not on a 4-byte boundary,}
         {we will trap.  If ptr has an unknown     }
         {virtual address, we will trap.  If the   }
         {virtual address is valid, but not        }
         {readable by our process, we will trap.   }
         {in all cases, the "trap" takes us to the }
         {recover block, with a non-0 value in     }
         {escapecode.                              }
      end

   recover
      begin
      result := 0;            {because the := above was interrupted}
      status := escapecode;   {oops, we trapped}
      end;

   end {load_from_iptr32 proc};
{********************************************************}
function hex32 (n : integer) : str32;

   var
      dummy       : integer;
      s           : str32;

   begin

   setstrlen (s, 8);
   dummy := dascii (n, 16, s);

   hex32 := '$' + s;

   end {hex32 proc};
{********************************************************}
function num32 (n : integer) : str32;

   var
      s           : str32;

   begin

   setstrlen (s, dascii (n, 10, s));

   num32 := s;

   end {num32 proc};
{********************************************************}
procedure test;

   var
      i           : integer;
      i16_array   : array [0..9] of shortint;
      test_data   : integer;

   {--------------------------}
   Procedure sub_test (addr : integer);

      const
         Trap_Ill_Pointer           =  3473608;      {HP-UX,MPE/iX}
         Trap_Data_Mem_Prot_Trap    =  3408072;      {HP-UX,MPE/iX}
         Trap_Instr_Mem_Prot_Trap   =  3408072;      {HP-UX,MPE/iX}

                  {above from: PASESC.PUB.SYS...                }
                  {                                             }
                  {Note that sometimes multiple errors share the}
                  {same error code!                             }
                  {                                             }
                  {NOTE: a misaligned address trap looks like   }
                  {a memory protection trap.                    }

      var
         altstatus: integer;
         i        : integer;
         ptr      : iptr32_type;
         status   : integer;

      begin

      ws ('---------------');

      ptr := iptr32_type (addr);

      load_from_iptr32 (status, ptr, i);

      if status = 0 then
         ws ('Load from ' + hex32 (addr) +
                  ' ok, data = ' +
                  num32 (i))

      else
         begin
         ws ('Load from ' + hex32 (addr) +
                  ' failed, status = ' +
                  hex32 (status) + ' (' +
                  num32 (status) +
                  '), data = ' + num32 (i));
         ws (' ');                     {blank line}

               {try to decode the status into an "english" msg...}

         if status = Trap_Ill_Pointer then
            ws ('Illegal Pointer')

         else if status = Trap_Data_Mem_Prot_Trap then
            ws ('Memory protection trap')

         else                 {...maybe in error catalog?}
            hperrmsg (2, 1, , status, , , altstatus);
                  {Note: the above "Trap_..." values are not}
                  {      in the system error catalog!       }
         end;

      ws (' ');               {blank line}

      end {sub_test Proc};
   {--------------------------}

   begin

   test_data := 123;
   for i := 0 to 9 do
      i16_array [i] := i;

         {tests that should work...}

   sub_test (baddress (test_data));

         {tests that should fail...}

   sub_test (-8);
   sub_test (3);
   sub_test (0);              {0 == NIL}

         {tests that may fail...}

   sub_test (hex ('80450000'));

         {tests that work only if load_from_iptr32 is }
         {compiled with USE2 option on...             }

   sub_test (baddress (i16_array [0]));
   sub_test (baddress (i16_array [1]));
   sub_test (baddress (i16_array [2]));
   sub_test (baddress (i16_array [3]));

   end {test proc};
{********************************************************}
procedure ws (s : str256);

   begin

   print (s, - strlen (s), 0);

   end {ws proc};
{********************************************************}

begin

test;

end.
--------------------------------------cut here----------------------------

--
Stan Sieler                                          [log in to unmask]
                                     http://www.allegro.com/sieler.html

ATOM RSS1 RSS2