[comp.unix.xenix.sco] SC Spreadhseet Calculator on sysV/386

cpcahil@virtech.uucp (Conor P. Cahill) (09/25/90)

In article <3486@ssc-bee.ssc-vax.UUCP> ian@ssc-vax.UUCP (Ian R. Searle) writes:
>Does anybody out there have sc running properly on sco unix or xenix
>sysV/386. I need a hand getting it to behave properly. I can
>sucessfully make sc and create an executable, but it constantly core
>dumps or dies due to xmallox/xfree errors. I cannot believe that
>anybody else would tolerate this behavior, and somebody must be
>using it on a 386, anybody???

If you are having problems with malloc/free, you might want to try my 
malloc debugging library that was posted to comp.sources.unix back in 
may/june.  It will go a long way to help solve malloc related problems.

BTW- I have an older version of sc (I thing from late last year) compiled
and working without any problems on our system (386/ix).  I haven't gotten
around to compiling/testing sc 6.8 yet.

-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

skwu@boulder.Colorado.EDU (WU SHI-KUEI) (09/26/90)

I am having similar problems on a 3B2/400 -- please help.

Thanks

john@jwt.UUCP (John Temples) (09/27/90)

In article <7915@scolex.sco.COM> seanf (Sean Fagan) writes:
>In article <3486@ssc-bee.ssc-vax.UUCP> ian@ssc-vax.UUCP (Ian R. Searle) writes:
>>Does anybody out there have sc running properly on sco unix or xenix
>>sysV/386.

Version 6.8 wouldn't compile with the AT&T compiler under ESIX-D.  "interp.c"
bombed off with "Fatal error in /lib/comp."  GCC produced a working
binary, but it did die with a core dump while I was going through the
tutorial file provided with the package.
-- 
John W. Temples -- john@jwt.UUCP (uunet!jwt!john)

richard@pegasus.com (Richard Foulk) (09/28/90)

>>>Does anybody out there have sc running properly on sco unix or xenix
>>>sysV/386.
>
>Version 6.8 wouldn't compile with the AT&T compiler under ESIX-D.  "interp.c"
>bombed off with "Fatal error in /lib/comp."  GCC produced a working
>binary, but it did die with a core dump while I was going through the
>tutorial file provided with the package.

On ISC 2.0.2 is works okay except that multiple divide-by-zero errors will
cause it to core dump (I think it dies no the fifth one).


-- 
Richard Foulk		richard@pegasus.com

hot@integow.uucp (Roland van Hout) (10/05/90)

From vn Fri Oct  5 11:22:36 1990
Subject: Re: SC  Spreadhseet Calculator on sysV/386
Newsgroups: comp.sources.d,comp.unix.sysv386,comp.unix.xenix.sco
References: <1990Sep28.164908.7116@pegasus.com>

From article <1990Sep28.164908.7116@pegasus.com>, by richard@pegasus.com (Richard Foulk):
> 
> On ISC 2.0.2 is works okay except that multiple divide-by-zero errors will
> cause it to core dump (I think it dies no the fifth one).
I have the same problem I used 6.2 6.8 6.9 and they all core dump with divide-by
zero errors. The 4.1 version which I have also doesnot have this problem, but
it's not nearly as nice as 6.9.
The x-es I tested are ISC 2.0.2 and Xenix 386 2.3.3.



-- 
UUCP: ..!uunet!mcsun!hp4nl!integow!hot	or  hot@integow.UUCP or hot@hot.mug
Roland van Hout, Sr. software engineer, Integrity software consultants, 
         Pelmolenlaan 16, 3447 GW Woerden, Netherlands,
            tel +31 3480-30131, fax +31 3480-30182
     Sex is not the answer, sex is the question. The answer is YES!

rgb@sequent.uucp (Bob Bond) (10/06/90)

Richard Foulk points out that sc core dumps after 5 divide by zero
errors.  The problem is that the 378 FPU state is not cleaned up
properly by the runtime system  (OS/C compiler) after an exception.

The 387 has a stack that the FP operands are pushed on before each
operation.  If the operation completes successfully, the stack is
popped and things go on their merry way.  If the operation errors out,
for example by a divide by 0, the operands are not popped.  So the next
operation adds a couple more operands, etc.  Eventually (after 5
errors) the stack fills and some innocent operation gets killed because
there is not enough stack space to hold its data.  Since the program
was not expecting that particular operation to generate an exception,
the program dumps core.

I have some disgusting, non-portable, 387 only code that does "asm
fpusave" and "asm fpurestore" operations at the right time.  If I get
enough response (please, mail only) I'll pass it on to Jeffery Buhrt so
he can post.

I'd suggest that rather than trying to patch in the asm code, you tell
your vendor about the problem :-).  In the meantime, the tried and true
(and easy) fix for this is to apply the following hack to interp.c and
stop most of the divide by 0's from happening in the first place.  This
is the way things used to be, in version 5.1 and before.

						Bob Bond
----------------------------
*** interp.c	Fri Oct  5 10:16:12 1990
--- interp.c.new	Fri Oct  5 10:14:26 1990
***************
*** 629,635
  	case '+':	return (eval(e->e.o.left) + eval(e->e.o.right));
  	case '-':	return (eval(e->e.o.left) - eval(e->e.o.right));
  	case '*':	return (eval(e->e.o.left) * eval(e->e.o.right));
! 	case '/':       return (eval(e->e.o.left) / eval(e->e.o.right));
  	case '%':     {	double num, denom;
  			num = floor(eval(e->e.o.left));
  			denom = floor(eval (e->e.o.right));

--- 629,636 -----
  	case '+':	return (eval(e->e.o.left) + eval(e->e.o.right));
  	case '-':	return (eval(e->e.o.left) - eval(e->e.o.right));
  	case '*':	return (eval(e->e.o.left) * eval(e->e.o.right));
! 	case '/':     { double denom = eval (e->e.o.right);
! 			       return denom ? eval(e->e.o.left) / denom : 0; }
  	case '%':     {	double num, denom;
  			num = floor(eval(e->e.o.left));
  			denom = floor(eval (e->e.o.right));

pcg@cs.aber.ac.uk (Piercarlo Grandi) (10/11/90)

On 28 Sep 90 16:49:08 GMT, richard@pegasus.com (Richard Foulk) said:

>>>Does anybody out there have sc running properly on sco unix or xenix
>>>sysV/386.

>Version 6.8 wouldn't compile with the AT&T compiler under ESIX-D.  "interp.c"
>bombed off with "Fatal error in /lib/comp."  GCC produced a working
>binary, but it did die with a core dump while I was going through the
>tutorial file provided with the package.

richard> On ISC 2.0.2 is works okay except that multiple divide-by-zero
richard> errors will cause it to core dump (I think it dies no the fifth
richard> one).

Here are a set of patches that eliminate some problems with sc 6.8, and
minimize the cases where divide-by-zero occur. In particular constant
expressions are only evaluated at load time, and non constant
expressions *are not* evaluated at load time, because this is both
useless and non sensical, because certain things may not be set up until
the entire spreadhseet has been loaded.

===================================================================
RCS file: interp.c,v
retrieving revision 6.8
diff -c -r6.8 interp.c
*** /tmp/,RCSt1a00165	Wed Sep 19 22:51:47 1990
--- interp.c	Wed Sep 19 22:40:30 1990
***************
*** 769,777 ****
  eval_fpe(signo) /* Trap for FPE errors in eval */
  int signo;
  {
  #ifdef IEEE_MATH
! 	(void)fpsetsticky((fp_except)0); 		/* Clear exception */
  #endif /* IEEE_MATH */
  	longjmp(fpe_save, 1);
  }
  
--- 769,782 ----
  eval_fpe(signo) /* Trap for FPE errors in eval */
  int signo;
  {
+ #ifdef i386
+ 	asm("	fnclex");
+ 	asm("	fwait");
+ #else
  #ifdef IEEE_MATH
! 	(void)fpsetsticky((fp_except)0);	/* Clear exception */
  #endif /* IEEE_MATH */
+ #endif
  	longjmp(fpe_save, 1);
  }
  
***************
*** 1130,1135 ****
--- 1135,1141 ----
  int i, j, *chgct;
  #endif
  {
+ 	(void) signal(SIGFPE, eval_fpe);
  	if (p->flags & is_strexpr) {
  	    char *v;
  	    if (setjmp(fpe_save)) {
***************
*** 1525,1569 ****
  struct enode *e;
  {
      double val;
  
!     exprerr = 0;
!     (void) signal(SIGFPE, eval_fpe);
!     if (setjmp(fpe_save)) {
! 	error ("Floating point exception in cell %s", v_name(v->row, v->col));
  	val = (double)0.0;
!     } else {
! 	val = eval(e);
!     }
!     (void) signal(SIGFPE, quit);
!     if (exprerr) {
! 	efree((struct ent *)0, e);
! 	return;
      }
!     if (constant(e)) {
! 	if (!loading)
! 	    v->v = val * prescale;
! 	else
! 	    v->v = val;
  	if (!(v->flags & is_strexpr)) {
              efree(v, v->expr);
  	    v->expr = (struct enode *)0;
  	}
  	efree((struct ent *)0, e);
-         v->flags |= (is_changed|is_valid);
-         changed++;
-         modflg++;
- 	return;
      }
!     efree (v, v->expr);
!     v->expr = e;
!     v->flags |= (is_changed|is_valid);
!     v->flags &= ~is_strexpr;
  
  #ifdef EXPRTREE
!     totoptree(v);
  #endif
!     changed++;
!     modflg++;
  }
  
  void
--- 1531,1581 ----
  struct enode *e;
  {
      double val;
+     unsigned isconstant = constant(e);
  
!     if (loading && !isconstant)
  	val = (double)0.0;
!     else
!     {
! 	exprerr = 0;
! 	(void) signal(SIGFPE, eval_fpe);
! 	if (setjmp(fpe_save)) {
! 	    error ("Floating point exception in cell %s", v_name(v->row, v->col));
! 	    val = (double)0.0;
! 	} else {
! 	    val = eval(e);
! 	}
! 	(void) signal(SIGFPE, quit);
! 	if (exprerr) {
! 	    efree((struct ent *)0, e);
! 	    return;
! 	}
      }
! 
!     if (isconstant) {
! 	if (!loading && prescale < (double)0.9999999)
! 	    val *= prescale;
! 	v->v = val;
! 
  	if (!(v->flags & is_strexpr)) {
              efree(v, v->expr);
  	    v->expr = (struct enode *)0;
  	}
  	efree((struct ent *)0, e);
      }
!     else
!     {
! 	efree (v, v->expr);
! 	v->expr = e;
! 	v->flags &= ~is_strexpr;
  
  #ifdef EXPRTREE
! 	totoptree(v);
  #endif
!     }
! 
!     v->flags |= (is_changed|is_valid);
!     changed++; modflg++;
  }
  
  void
===================================================================
RCS file: lex.c,v
retrieving revision 6.8
diff -c -r6.8 lex.c
*** /tmp/,RCSt1a00165	Wed Sep 19 22:51:52 1990
--- lex.c	Mon Sep 17 11:06:40 1990
***************
*** 56,61 ****
--- 56,78 ----
  jmp_buf wakeup;
  jmp_buf fpe_buf;
  
+ #ifdef SIGVOID
+ void
+ #endif
+ fpe_trap(signo)
+ int signo;
+ {
+ #ifdef i386
+ 	asm("	fnclex");
+ 	asm("	fwait");
+ #else
+ #ifdef IEEE_MATH
+ 	(void)fpsetsticky((fp_except)0);	/* Clear exception */
+ #endif /* IEEE_MATH */
+ #endif
+     longjmp(fpe_buf, 1);
+ }
+ 
  struct key {
      char *key;
      int val;
***************
*** 136,146 ****
  	    }
  	}
      } else if ((*p == '.') || isdigit(*p)) {
! 	double v = 0;
  	int temp;
  	char *nstart = p;
  	if (*p != '.') {
! 	    do v = v*10 + (double)(*p-'0');
  	    while (isdigit(*++p));
  	}
  	if (*p=='.' || *p == 'e' || *p == 'E') {
--- 153,177 ----
  	    }
  	}
      } else if ((*p == '.') || isdigit(*p)) {
! #ifdef SIGVOID
! 	void (*sig_save)();
! #else
! 	int (*sig_save)();
! #endif
! 	double v = 0.0;
  	int temp;
  	char *nstart = p;
+ 
+ 	sig_save = signal(SIGFPE, fpe_trap);
+ 	if (setjmp(fpe_buf)) {
+ 	    (void) signal(SIGFPE, sig_save);
+ 	    yylval.fval = v;
+ 	    error("Floating point exception\n");
+ 	    return FNUMBER;
+ 	}
+ 
  	if (*p != '.') {
! 	    do v = v*10.0 + (double) ((unsigned) *p - '0');
  	    while (isdigit(*++p));
  	}
  	if (*p=='.' || *p == 'e' || *p == 'E') {
***************
*** 163,168 ****
--- 194,200 ----
  		}
  	    }
  	}
+ 	(void) signal(SIGFPE, sig_save);
      } else if (*p=='"') {
  	char *ptr;
          ptr = p+1;
***************
*** 539,557 ****
  time_out(signo)
  int signo;
  {
! #ifdef IEEE_MATH
! 	(void)fpsetsticky((fp_except)0); 		/* Clear exception */
! #endif /* IEEE_MATH */
!     longjmp(wakeup, -1);
! }
! 
! #ifdef SIGVOID
! void
! #endif
! fpe_trap(signo)
! int signo;
! {
!     longjmp(fpe_buf, 1);
  }
  
  /*
--- 571,577 ----
  time_out(signo)
  int signo;
  {
!     longjmp(wakeup, 1);
  }
  
  /*
--
Piercarlo "Peter" Grandi           | ARPA: pcg%uk.ac.aber.cs@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

richard@pegasus.com (Richard Foulk) (10/14/90)

>Here are a set of patches that eliminate some problems with sc 6.8, and
>minimize the cases where divide-by-zero occur. In particular constant
>expressions are only evaluated at load time, and non constant
>expressions *are not* evaluated at load time, because this is both
>useless and non sensical, because certain things may not be set up until
>the entire spreadhseet has been loaded.

Well your patch doesn't seem to fix the real problem.  Divide by zero
still kills it.

I'm curious what do these actually do:

>+ 	asm("	fnclex");
>+ 	asm("	fwait");

And if some sort of stack overflow on the 387 (or emulator in my case)
is the problem, why can't this be fixed with a few assembler
instructions to clean up the 387?  In case you haven't guessed, I know
very little about the 387 and I don't have any docs on it.


-- 
Richard Foulk		richard@pegasus.com