Subject: | |
From: | |
Reply To: | |
Date: | Mon, 7 Aug 2000 15:43:49 -0700 |
Content-Type: | text/plain |
Parts/Attachments: |
|
|
Re:
> Stan Sieler ([log in to unmask]) wrote:
> : There are some kinds of traps that try/recover will not be able to
> : handle, even though one would think it should. E.g., a LDW with a bad
> : address.
>
> This works perfectly fine, at least on HP-UX.
No...you took me out of context. The full context made it clear that I'm
saying: there are some cases where a non-local escape (which is the kind
caused by a LDW, not that I'm limiting the discussion to LDW) will
emphatically *NOT* be caught by a try/recover. This happens because we
use "cheap try / expensive recover". As a result, it's possible that if
the stack marker is corrupted, we won't be able to find the matching
(or, possibly, *any*) recover block.
Below is a sample of this fact. Here's a sampel run, HP-UX 10.20:
Welcome to the cause_trap test program!
Calling "safely"...
causing trap...
Caught first LDW trap ok!
Calling "unsafely"...
WARNING: corrupting stack!
causing trap...
Signal 10: bus error
PROCEDURE TRACEBACK:
( 0) 0x00002510 cause_trap + 0x164 [././trapper]
Note that the point here is that one cannot always rely on try/recover...
doing so is simply wrong. One must be aware that some kinds of problems
won't be catchable via try/recover. Does that mean that we shouldn't
use try/recover? Of course not! It's a good feature, and I use it in
many areas.
(Hmm...I thought I told you about this in my internals class, Dennis :)
----------------------------------cut here----------------------------------
$standard_level 'os_features'$
$type_coercion 'representation'$
program m (output);
type
ip64 = ^$extnaddr$ integer;
str16 = string [16];
str80 = string [80];
twoints = array [1..2] of integer;
var
i : integer;
lptr : ip64;
mysid : integer;
offset : integer;
sid : integer;
{*****************************************************************}
procedure cause_trap (want_corruption : boolean);
var
i : integer;
ktr : integer;
lptr : ip64;
begin
$push, range off$ {avoid alignment checking code}
{we know that the manipulation of lptr we are doing below}
{will not result in bad alignment ... you'd think the compiler}
{would know that too! (because "i" is aligned, and -4 is the }
{size of an integer)}
if want_corruption then
begin
writeln (' WARNING: corrupting stack!');
lptr := addr (i);
for ktr := 1 to 20 do
begin
lptr^ := 0;
lptr := addtopointer (lptr, -4);
end;
end;
$pop$ {range}
$push, range off$ {avoid alignment checking code}
{We want to build a bad pointer on purpose...so we can}
{de-reference it within a try/recover block. }
lptr := addtopointer (addr (i), 1);
$pop$ {range}
writeln (' causing trap...');
i := lptr^;
{We shouldn't get back here, becase the above}
{assignment should have trapped! }
writeln ('OOPS...failed to trap!');
end {cause_trap proc};
{*****************************************************************}
begin
writeln ('Welcome to the cause_trap test program!');
writeln;
writeln ('Calling "safely"...');
{Note: neither "recover" block below should get triggered}
try
cause_trap (false);
recover
writeln ('Caught first LDW trap ok!');
writeln;
writeln ('Calling "unsafely"...');
try
cause_trap (true);
recover
writeln ('Wow...we caught the second LDW trap...I''m surprised!');
end.
----------------------------------cut here----------------------------------
Stan Sieler [log in to unmask]
www.allegro.com/sieler/wanted/index.html www.allegro.com/sieler
|
|
|