T.R | Title | User | Personal Name | Date | Lines |
---|
2176.1 | | TLE::REAGAN | Use only as directed | Wed Mar 10 1993 12:10 | 43 |
2176.2 | example for $UNWIND, please ! | LNZALI::BACHNER | Mouse not found. Click OK to continue | Tue Mar 18 1997 13:27 | 25 |
| The example in .1 works fine, but I've benn unable to come up with a working
example of using $UNWIND instead of the non-local GOTO.
Whatever I try, the condition handler is entered a second time (apparently
during $UNWIND processing) with the infamous CANCNTERR error.
My condition handler looks about like
[asynchronous] function my_hand ( var sigargs : sigarr;
var mechargs : mecharr) : integer;
begin
lib$put_output('*** error handler invoked ***');
if sigargs[1] = pas$_substrsel
then
$unwind (mechargs[2] + 1, 0) { mechargs[4] on OpenVMS Alpha }
else
my_hand := ss$_resignal;
end;
Any suggestion how to make the $UNWIND work ?
(This is only a demonstration example, not the real handler)
Thanks for your help,
Hans.
|
2176.3 | | QUARK::LIONEL | Free advice is worth every cent | Tue Mar 18 1997 14:39 | 4 |
| Are you trying to unwind to the frame that got the error? You can't do that -
you have to unwind at least one more frame.
Steve
|
2176.4 | Same guy? | QUARK::LIONEL | Free advice is worth every cent | Tue Mar 18 1997 15:05 | 73 |
| From: "D.I. Martin Michalecz, TeleControl Wien, Austria"
<MICHALECZ%[email protected]>
Newsgroups: comp.os.vms
Subject: LIB$SIG_TO_RET conflicts with DEC PASCAL RTL
Message-ID: <[email protected]>
Date: Tue, 18 Mar 1997 19:59:14 MET
Organization: Info-Vax<==>Comp.Os.Vms Gateway
X-Gateway-Source-Info: Mailing List
Lines: 63
I have the following problem with a PASCAL condition handler. As I know some
people of DEC's PASCAL group scan this list, I would appreciate some statement.
System Versions
AXP OVMS V6.2
PASCAL V5.5-Eco2
The following program does NOT what expected. I expected, that function "sub"
would return with (some) error status. This is the normal behavior of
LIB$SIG_TO_RET.
[ inherit ( 'sys$share:pascal$lib_routines' ) ]
program ss;
var s : string(80) := '';
function sub : integer ;
begin
establish (lib$sig_to_ret);
s := substr ( s , 1 , 1 );
return length (s);
end;
begin sub end.
%PAS-F-CANCNTERR, handler cannot continue from a nonfile error
%TRACE-F-TRACEBACK, symbolic stack dump follows
Image Name Module Name Routine Name Line Number rel PC abs PC
PAS$RTL 0 00037B40 00079B40
----- above condition handler called with exception 0021BEE4:
%PAS-F-SUBSTRSEL, SUBSTR or substring-access selection error
----- end of exception message
0 8E5622BC 8E5622BC
SS SS SUB 10 000000E4 000200E4
SS SS SS 14 00000180 00020180
0 8E670170 8E670170
Examination of the VESTED AXP PASCAL RUNTIME LIBRARY of V6.1 (I didn't find the
"normal" PASRTL on the VMS Listings CD :-( ?) solved the problem:
For exceptions coded by runtime checking code, a special part of the PASCAL
internal exception handler is used. This part prohibits continuation by
SS$_CONTINUE. *BUT* I do NOT want to continue, I want to return. LIB$SIG_TO_RET
seems to manipulate the return stack only and then return with SS$_CONTINUE.
Please do NOT tell me to use a non local GOTO. It works well, but adding one
line
ESTABLISH( LIB$SIG_TO_RET )
is very simple, while adding conditionhandlerCODE to several routines tends to
produce coding errors.
I think this is a BUG in the PASCAL RTL - it is TOO restriktive !
Martin Michalecz
Telecontrol Vienna
PS. I have posted a question to DEC support channel in Autria, too.
|
2176.5 | My response | QUARK::LIONEL | Free advice is worth every cent | Tue Mar 18 1997 15:09 | 25 |
| [I note that he provided details in his newsgroup posting that haven't been
seen in this note.]
In article <[email protected]>, "D.I. Martin Michalecz,
TeleControl Wien, Austria" <MICHALECZ%[email protected]> writes:
|>I have the following problem with a PASCAL condition handler. As I know some
|>people of DEC's PASCAL group scan this list, I would appreciate some statement.
|>
|>PS. I have posted a question to DEC support channel in Autria, too.
Yes, and they properly passed it on to the Pascal engineers who have provided
a response - and they are working on coming up with an alternate solution
for you.
The problem is that when you establish LIB$SIG_TO_RET as a handler, the
Pascal RTL calls it and looks at its return status, which is SS$_CONTINUE.
The Pascal RTL doesn't know that LIB$SIG_TO_RET has called $UNWIND (which
would cause the return status to be ignored), and thus complains that this
particular error can't be continued. (You can probably blame me for this -
I designed and implemented the original RTL for VAX PASCAL V2 and later.)
I haven't tried this, but it seems to me that a solution is to write a
"jacket" handler routine which you establish - this routine calls
LIB$SIG_TO_RET but returns SS$_RESIGNAL. The Pascal RTL should be happy
with that.
|
2176.6 | | TLE::REAGAN | All of this chaos makes perfect sense | Tue Mar 18 1997 15:32 | 8 |
| I'll read the notes and write up some examples and additional
documention about when you can and cannot unwind back to the frame
with an error. In general, assume that you cannot unwind back to the
frame with the error. I think you'll find that the list of when
you can or cannot will differ from VAX to Alpha. Relying on the
generated code isn't very portable or safe.
-John
|
2176.7 | | TLE::REAGAN | All of this chaos makes perfect sense | Tue Mar 18 1997 16:34 | 25 |
| Well, I'll let Steve Lional off the hook. When he last left the code,
the RTL's handler simply returned after the user's handler was called.
In 1984, in response to several customers who got into infinite loops
trying to continue from a certain class of run-time errors, we added some
code to the RTL to complain if a user handler returned SS$_CONTINUE for
these errors. The errors are the checking code for the SUBSTR and PAD
builtins as well as checking code for set constuctors (ie, [x..y]). As
we see in the customer's example, they are indeed using the SUBSTR()
builtin.
This is the 1st time since 1984 that this issue has come up. We didn't
think about it then. Is the RTL too restrictive? Perhaps. I'll think
about what I could do the RTL to let LIB$SIG_TO_RET work as well as
telling customers they are about to go into an infinite loop trying to
continue on errors that are not meant to be continued from.
I think Steve's suggestion of using jacket routine that calls
LIB$SIG_TO_RET and returns SS$_RESIGNAL is the right solution in the
short-term.
I'll even add something to the release notes for this case.
-John
|
2176.8 | | TLE::REAGAN | All of this chaos makes perfect sense | Tue Mar 18 1997 16:36 | 3 |
| BTW, I posted my reponse in .7 back into comp.os.vms.
-John
|
2176.9 | | QUARK::LIONEL | Free advice is worth every cent | Tue Mar 18 1997 20:12 | 11 |
| Geez - at least you could spell my name right! :-)
The trouble is that I can't think of how the RTL could detect that
a $UNWIND had been done - at least, reliably. You could look for the
special address that $UNWIND puts in the return PC field in the stack
frame, but this is a dependency I would not favor adding.
My advice is to just put in a release note or other documentation
suggesting the workaround for such cases.
Steve
|
2176.10 | ... and how can I make $UNWIND work ? | LNZALI::BACHNER | Mouse not found. Click OK to continue | Wed Mar 19 1997 04:49 | 21 |
| Re .4: Same guy ?
Yes, exactly.
Re .5: [I note that he provided details in his newsgroup posting that haven't
Re .5: been seen in this note.]
That's true. I already found our that for some errors SS$_CONTINUE is not
allowed (looking forward to your list, John ;-) and only the non-local GOT or
the unwind was an alternative.
Using the non-local GOTO is a trivial task but I was unable to produce a working
example with $UNWIND. I tried both unwinding to the establisher and to the
establisher's caller but always got the second handler invocation with the
CANCNTERR as mentioned in .2.
So I reduced the customers question to 'how can I make $UNWIND work in a Pascal
condition handler ?'.
Thanks,
Hans.
|
2176.11 | | TLE::REAGAN | All of this chaos makes perfect sense | Wed Mar 19 1997 09:35 | 77 |
| There are examples in the User Manual for handlers.
Here is one I whipped up and tested on an OpenVMS Alpha machine.
[inherit('sys$library:starlet')]
program handler(input,output);
type
sig_args_type = array [0..100] of integer;
mech_args_type = array [0..(size(chf2$type)-4)div 4] of integer;
[asynchronous] function handler
(var sig_args : sig_args_type;
var mech_args : mech_args_type ) : integer;
var f : text;
begin
if sig_args[1] <> ss$_unwind
then
begin
{ If we're not already unwinding, print out the error we have }
{ and unwind back to the caller of the establisher. }
open(f,'sys$output',history:=old);
rewrite(f);
writeln(f,'In the handler with error = ',hex(sig_args[1]));
close(f);
$unwind;
end;
handler := ss$_resignal;
end;
procedure b;
var i,j : [volatile] integer;
begin
writeln('Entering routine b');
{ Force a divide-by-zero }
j := 0;
i := j div j;
writeln('Exiting routine b');
end;
procedure a;
begin
writeln('Entering routine a');
establish(handler);
b;
writeln('Exiting routine a');
end;
begin
writeln('About to call routine a');
a;
writeln('Returned back to main program from routine a');
end.
(hiyall)$ run handler
About to call routine a
Entering routine a
Entering routine b
In the handler with error = 00000484
Returned back to main program from routine a
You can see that the $UNWIND skipped the rest of 'a' and 'b' from executing
and returned all the way back to the main routine (ie, the caller of the
establisher).
-John
|
2176.12 | silly me | LNZALI::BACHNER | Mouse not found. Click OK to continue | Wed Mar 19 1997 11:34 | 13 |
| Thanks for the example.
The problem in my test program was that I did not set the return value to
SS$_RESIGNAL after the $UNWIND call.
I've talked to the customer in the meantime. He has tried the jacket handler as
suggested by Steve but has problems to detect the original failure status after
the $unwind. I'll try to come up with a solution.
He will no longer post replies to this thread in comp.os.vms except for a final
summary. He choose to follow the 'official' channels.
Hans.
|
2176.13 | | AUSS::GARSON | DECcharity Program Office | Wed Mar 19 1997 18:32 | 10 |
| re .12
>The problem in my test program was that I did not set the return value to
>SS$_RESIGNAL after the $UNWIND call.
As far as I know, SYS$UNWIND ignores the return status from condition
handlers that it calls during the unwind. (On the other hand since
PASCAL is presumably establishing its own condition handler and explicitly
invoking your handler routine, it is conceivable that PASCAL might care
about your return status.)
|