[comp.lang.pascal] Help with stack overflow

dor@beach.cis.ufl.edu (Douglas R. Oosting) (04/11/90)

I have a fairly large communications program in Turbo 5.0 which just 
(apparently) dumped with a stack overflow.  Ouch.  How can I trap something
like this?  I have the ExitPtr pointer set to a FAR routine {$F+} that
has no local variables (everything called in it is global to that unit)

Is there a kind soul out there who can help me?  I don't have a recursing
routine that should be causing this stack dump in the FIRST place...it would
help if I could trap it (the screen is cleared by the calling program so I
can't see the message given me by TURBO's exit code anyway...so I have *no*
idea where in the program this is happening...and the communications part
of the program keeps me from running the debugger on it...)

Thanks,
Doug 


--
And in the end/the love you take | Douglas R. Oosting, University of Florida
   is equal to/the love you make | dor@beach.cis.ufl.edu | dro@gnv.ifas.ufl.edu 
FNORD!--------The Earth is Our Mother, treat her with respect------------FNORD!
In the Society : Cadrys ap Dulas o Caereira, Barony of An Crosaire, Trimaris

pmk@cip-s01.informatik.rwth-aachen.de (Michael Keukert) (04/12/90)

In article <22863@uflorida.cis.ufl.EDU> dor@beach.cis.ufl.edu (Douglas R. Oosting) writes:
>I have a fairly large communications program in Turbo 5.0 which just 
>(apparently) dumped with a stack overflow.  Ouch.  How can I trap something
>like this?  I have the ExitPtr pointer set to a FAR routine {$F+} that
>has no local variables (everything called in it is global to that unit)
>

Hi,

There are three variables, which are useful to you.

ExitProc has to be set on the (far-compiled) error handling routine,
like you already did it. For the others:
  ExitProc := @own_exit_proc_name;

ExitCode get`s a number between 0 and 255 which will indicate, what
  error occured.

ErrorAddr is a pointer variable, which includes the segment and offset
  of the address where the error occured.

You now have to declare your own, error handling procedure, which has to 
be far-compiled and whic mustn`t use external parameters. Within the
procedure, you can reference other procedure or use as much variables
you like.

DANGER!!!!

The normal TPascal exit-procedure HAS TO BE executed also, because it
closes the files, reconstructs the interrupt vectors etc. So you have
to save the original pointer first:

 SaveExitProc := ExitProc;

Within your own procedure, you can set ErrorAddr to NIL. Doing this will
cause no other errors. This means, your own procedure isn`t itself 
interrupted by a runtime error.
Don`t forget to reload the exitproc BEFORE exiting your own procedure:
 ExitProc := SaveExitProc;

Now a tiny example:

{$f+}
PROCEDURE myexit;
VAR i:INETEGER;
BEGIN
 WRITELN(`Error Number : `,ExitCode);
 ErrorAddr := NIL;
 ExitProc := SaveExitProc;
END;

{$F-}


BEGIN {main}
 SaveExitProc := ExitProc;
 ExitProc := @myexit;
 [...]
END.

If you want to get the address of ErrorAddr, use this:

TYPE errorptr =
	 segment:word;
	 offset:word;
        end;

WRITELN (`Error at : `,errorptr(erroraddr).segment,`:`,errorptr(erroraddr).offset;

This is known as TYPECASTING and allows you, to enable the compiler-range
check. For example:

VAR a:BYTE;
    b:STRING;

a:=12;
b:=STRING(a);

For the results of typecasting, the programmer has to take care. No
garantees are given ;-)

OK, hope I helped you....

---------------------------------------------------------------------------
Michael Keukert, Elsasstrasse 58, D-5100 Aachen, FRG, Tel: +49 241 513297 Q
Fido: Michael Keukert@Maus AC 2:242/2   ZNet:MICHAEL_KEUKERT!AC@ZERMAUS.ZER
Twenty bucks per day plus expenses - hundred in advance.        (Sam Spade)

dor@beach.cis.ufl.edu (Douglas R. Oosting) (04/13/90)

In article <2577@rwthinf.UUCP> pmk@cip-s01.UUCP (Michael Keukert) writes:
[a very long and detailed way to implement automatic exit code and error
handler in Turbo 5.0, deleted.]

That IS the way I have this done...it works properly too..HOWEVER, the
problem with this method is when the error is a stack overflow,
MY ROUTINE DOES *NOT* EXECUTE.  Apparently, seeing as it is a user routine,
Turbo refuses to try to run it as it cannot push it onto the stack.
That is the thrust of my question...apparetnly there are pointers in the
SYSTEM unit (stackptr and stacklimit or something like that) which could
be used to determine the current stack size...but it seems a mite cumbersome
(if not well-nigh impossible) to check these before every function call!

I did neglect ot mention that my stack size for the program is set to the
max that turbo will handle ... 65520 bytes...

Any other input?  Thanks...
Doug Oosting

--
And in the end/the love you take | Douglas R. Oosting, University of Florida
   is equal to/the love you make | dor@beach.cis.ufl.edu | dro@gnv.ifas.ufl.edu 
FNORD!--------The Earth is Our Mother, treat her with respect------------FNORD!
In the Society : Cadrys ap Dulas o Caereira, Barony of An Crosaire, Trimaris