[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::pascal

Title:DEC Pascal Notes
Notice:See note 1 for kits. Bug reports to CLT::DEC_PASCAL_BUGS
Moderator:TLE::REAGAN
Created:Sat Jan 25 1986
Last Modified:Tue Jun 03 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:2675
Total number of notes:13409

2176.0. "condition handler for rtl-routines without returnstatus" by MUNICH::PFLUGER () Wed Mar 10 1993 14:07

T.RTitleUserPersonal
Name
DateLines
2176.1TLE::REAGANUse only as directedWed Mar 10 1993 15:1043
2176.2example for $UNWIND, please !LNZALI::BACHNERMouse not found. Click OK to continueTue Mar 18 1997 16:2725
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.3QUARK::LIONELFree advice is worth every centTue Mar 18 1997 17:394
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.4Same guy?QUARK::LIONELFree advice is worth every centTue Mar 18 1997 18:0573
From: "D.I. Martin Michalecz, TeleControl Wien, Austria"
      <MICHALECZ%EWCLU.dnet@RZCLU.prod.vie.tc>
Newsgroups: comp.os.vms
Subject: LIB$SIG_TO_RET conflicts with DEC PASCAL RTL
Message-ID: <009B175F.5155A4E6.871@RZCLU.prod.vie.tc>
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.5My responseQUARK::LIONELFree advice is worth every centTue Mar 18 1997 18:0925
[I note that he provided details in his newsgroup posting that haven't been
seen in this note.]

In article <009B175F.5155A4E6.871@RZCLU.prod.vie.tc>, "D.I. Martin Michalecz, 
TeleControl Wien, Austria"       <MICHALECZ%EWCLU.dnet@RZCLU.prod.vie.tc> 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.6TLE::REAGANAll of this chaos makes perfect senseTue Mar 18 1997 18:328
    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.7TLE::REAGANAll of this chaos makes perfect senseTue Mar 18 1997 19:3425
    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.8TLE::REAGANAll of this chaos makes perfect senseTue Mar 18 1997 19:363
    BTW, I posted my reponse in .7 back into comp.os.vms.
    
    				-John
2176.9QUARK::LIONELFree advice is worth every centTue Mar 18 1997 23:1211
    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::BACHNERMouse not found. Click OK to continueWed Mar 19 1997 07:4921
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.11TLE::REAGANAll of this chaos makes perfect senseWed Mar 19 1997 12:3577
    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.12silly meLNZALI::BACHNERMouse not found. Click OK to continueWed Mar 19 1997 14:3413
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.13AUSS::GARSONDECcharity Program OfficeWed Mar 19 1997 21:3210
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.)