From 490887591e611930069d8ed24942b0c1f92038b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 10 Aug 1998 16:33:31 -0700
Subject: [PATCH] stack checks and -ss<thread stack size> implemented

Rev: src/configure.in:1.230
Rev: src/interpret.c:1.94
Rev: src/interpret.h:1.22
Rev: src/main.c:1.57
Rev: src/testsuite.in:1.120
Rev: src/threads.c:1.80
Rev: src/threads.h:1.48
---
 src/configure.in | 60 ++++++++++++++++++++++++------------------------
 src/interpret.c  | 16 +++++++++----
 src/interpret.h  |  3 ++-
 src/main.c       | 48 +++++++++++++++++++++++++++++++++++---
 src/testsuite.in |  3 ++-
 src/threads.c    |  6 +++--
 src/threads.h    |  8 +++++--
 7 files changed, 100 insertions(+), 44 deletions(-)

diff --git a/src/configure.in b/src/configure.in
index 10b97c8b3c..0955dfe765 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1,4 +1,4 @@
-AC_REVISION("$Id: configure.in,v 1.229 1998/08/09 14:43:06 grubba Exp $")
+AC_REVISION("$Id: configure.in,v 1.230 1998/08/10 23:33:28 hubbe Exp $")
 AC_INIT(interpret.c)
 AC_CONFIG_HEADER(machine.h)
 
@@ -1406,35 +1406,35 @@ esac
 OLD_LIBOBJS="${LIBOBJS}"
 
 ########################################################################
-dnl AC_MSG_CHECKING(stack direction)
-dnl AC_CACHE_VAL(pike_cv_hardware_stack_direction,
-dnl [
-dnl AC_TRY_RUN([
-dnl static int find_stack_direction ()
-dnl {
-dnl   static char	*addr = NULL;
-dnl   char dummy;
-dnl   if (addr == NULL)
-dnl   {
-dnl       addr = &dummy;
-dnl       return find_stack_direction();
-dnl   }
-dnl   else
-dnl   {
-dnl     if (&dummy > addr) return 1; else return -1;
-dnl   }
-dnl }
-dnl 
-dnl int main() { exit( find_stack_direction() < 0); }
-dnl ],pike_cv_hardware_stack_direction=up,pike_cv_hardware_stack_direction=down)
-dnl ])
-dnl 
-dnl AC_MSG_RESULT($pike_cv_hardware_stack_direction)
-dnl if test x$pike_cv_hardware_stack_direction = up ; then
-dnl   AC_DEFINE(STACK_DIRECTION, 1)
-dnl else
-dnl   AC_DEFINE(STACK_DIRECTION, -1)
-dnl fi
+AC_MSG_CHECKING(stack direction)
+AC_CACHE_VAL(pike_cv_hardware_stack_direction,
+[
+AC_TRY_RUN([
+static int find_stack_direction ()
+{
+  static char	*addr = NULL;
+  char dummy;
+  if (addr == NULL)
+  {
+      addr = &dummy;
+      return find_stack_direction();
+  }
+  else
+  {
+    if (&dummy > addr) return 1; else return -1;
+  }
+}
+
+int main() { exit( find_stack_direction() < 0); }
+],pike_cv_hardware_stack_direction=up,pike_cv_hardware_stack_direction=down)
+])
+
+AC_MSG_RESULT($pike_cv_hardware_stack_direction)
+if test x$pike_cv_hardware_stack_direction = up ; then
+  AC_DEFINE(STACK_DIRECTION, 1)
+else
+  AC_DEFINE(STACK_DIRECTION, -1)
+fi
 
 ########################################################################
 
diff --git a/src/interpret.c b/src/interpret.c
index 2014d3a316..1e99588d63 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.93 1998/07/28 23:02:42 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.94 1998/08/10 23:33:29 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -61,6 +61,7 @@ struct svalue *sp;     /* Current position */
 struct svalue *evaluator_stack; /* Start of stack */
 int stack_size = EVALUATOR_STACK_SIZE;
 int evaluator_stack_malloced = 0;
+char *stack_top;
 
 /* mark stack, used to store markers into the normal stack */
 struct svalue **mark_sp; /* Current position */
@@ -192,6 +193,14 @@ void check_mark_stack(INT32 size)
     error("Stack overflow.\n");
 }
 
+void check_c_stack(INT32 size)
+{
+  long x=((char *)&size) + STACK_DIRECTION * size - stack_top ;
+  x*=STACK_DIRECTION;
+  if(x>0)
+    error("Stack overflow.\n");
+}
+
 
 static int eval_instruction(unsigned char *pc);
 
@@ -1893,15 +1902,12 @@ void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2)
       
       check_stack(256);
       check_mark_stack(256);
+      check_c_stack(8192);
 
 #ifdef DEBUG
       if(d_flag>2) do_debug();
 #endif
 
-      /* If we are really unlucky, o hasn't just been destructed, it has
-       * also been freed!
-       */
-
       p=o->prog;
       if(!p)
 	PIKE_ERROR("destructed object->function",
diff --git a/src/interpret.h b/src/interpret.h
index de31fc0fe0..5823f9c34e 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: interpret.h,v 1.21 1998/06/06 03:25:37 hubbe Exp $
+ * $Id: interpret.h,v 1.22 1998/08/10 23:33:29 hubbe Exp $
  */
 #ifndef INTERPRET_H
 #define INTERPRET_H
@@ -155,6 +155,7 @@ extern struct svalue **mark_sp;
 extern struct svalue *evaluator_stack;
 extern struct svalue **mark_stack;
 extern struct frame *fp; /* frame pointer */
+extern char *stack_top;
 extern int stack_size;
 extern int evaluator_stack_malloced, mark_stack_malloced;
 struct callback;
diff --git a/src/main.c b/src/main.c
index 126794f090..7041adbb19 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: main.c,v 1.56 1998/07/27 21:57:11 hubbe Exp $");
+RCSID("$Id: main.c,v 1.57 1998/08/10 23:33:30 hubbe Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include "module.h"
@@ -194,8 +194,30 @@ int dbm_main(int argc, char **argv)
 	      exit(1);
 	    }
 	    p=argv[e];
+	  }else{
+	    p++;
+	    if(*p=='s')
+	    {
+	      if(!p[1])
+	      {
+		e++;
+		if(e >= argc)
+		{
+		  fprintf(stderr,"Missing argument to -ss\n");
+		  exit(1);
+		}
+		p=argv[e];
+	      }else{
+		p++;
+	      }
+#ifdef _REENTRANT
+	      thread_stack_size=STRTOL(p,&p,0);
+#endif
+	      p+=strlen(p);
+	      break;
+	    }
 	  }
-	  stack_size=STRTOL(p+1,&p,0);
+	  stack_size=STRTOL(p,&p,0);
 	  p+=strlen(p);
 
 	  if(stack_size < 256)
@@ -215,8 +237,10 @@ int dbm_main(int argc, char **argv)
 	      exit(1);
 	    }
 	    p=argv[e];
+	  }else{
+	    p++;
 	  }
-	  instructions_left=STRTOL(p+1,&p,0);
+	  instructions_left=STRTOL(p,&p,0);
 	  p+=strlen(p);
 	  add_to_callback(&evaluator_callbacks,
 			  time_to_exit,
@@ -299,6 +323,24 @@ int dbm_main(int argc, char **argv)
 #define RLIMIT_NOFILE RLIMIT_OFILE
 #endif
 
+#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK)
+  {
+    struct rlimit lim;
+    if(!getrlimit(RLIMIT_STACK, &lim))
+    {
+#ifdef RLIM_INFINITY
+      if(lim.rlim_cur == RLIM_INFINITY)
+	lim.rlim_cur=1024*1024*128;
+#endif
+      stack_top= ((char *) &argv) + 
+	STACK_DIRECTION * (lim.rlim_cur - 8192 * sizeof(char *));
+    }
+  }
+#else
+  stack_top= ((char *) &argv) + 
+    STACK_DIRECTION * (1024*1024 * 128 - 8192 * sizeof(char *));
+#endif
+
 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
   {
     struct rlimit lim;
diff --git a/src/testsuite.in b/src/testsuite.in
index afa344f3c6..3d44c8f8ee 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-stest_true([["$Id: testsuite.in,v 1.119 1998/08/05 22:50:11 hubbe Exp $"]])
+stest_true([["$Id: testsuite.in,v 1.120 1998/08/10 23:33:30 hubbe Exp $"]])
 cond([[all_constants()->_verify_internals]],
 [[
   test_do(_verify_internals())
@@ -70,6 +70,7 @@ test_compile([[Stdio.File foo=Stdio.FILE();]])
 dnl this should really work...
 dnl test_compile_any([[void foo(int,string,...);]])
 
+test_eval_error([[class X { int create() { create(); } }();]])
 test_compile_error([[ int float; ]])
 test_compile_error([[ int array; ]])
 test_compile_error([[ int function; ]])
diff --git a/src/threads.c b/src/threads.c
index f581827bd1..54d40fc64b 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.79 1998/07/17 22:37:11 hubbe Exp $");
+RCSID("$Id: threads.c,v 1.80 1998/08/10 23:33:31 hubbe Exp $");
 
 int num_threads = 1;
 int threads_disabled = 0;
@@ -19,6 +19,7 @@ int threads_disabled = 0;
 int live_threads = 0;
 COND_T live_threads_change;
 COND_T threads_disabled_change;
+size_t thread_stack_size=1024 * 1204;
 
 #ifdef __NT__
 
@@ -450,6 +451,7 @@ void *new_thread_func(void * data)
   thread_id=arg.id;
   SWAP_OUT_THREAD((struct thread_state *)thread_id->storage); /* Init struct */
   ((struct thread_state *)thread_id->storage)->swapped=0;
+  stack_top=((char *)&data)+ (thread_stack_size-16384) * STACK_DIRECTION 
 #ifdef THREAD_TRACE
   {
     t_flag = default_t_flag;
@@ -881,7 +883,7 @@ void low_th_init(void)
 #ifdef POSIX_THREADS
   pthread_attr_init(&pattr);
 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
-  pthread_attr_setstacksize(&pattr, 1024 * 1204);
+  pthread_attr_setstacksize(&pattr, thread_stack_size);
 #endif
   pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
 
diff --git a/src/threads.h b/src/threads.h
index 9542577b46..ef4989bfcc 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -1,5 +1,5 @@
 /*
- * $Id: threads.h,v 1.47 1998/08/06 19:46:56 grubba Exp $
+ * $Id: threads.h,v 1.48 1998/08/10 23:33:31 hubbe Exp $
  */
 #ifndef THREADS_H
 #define THREADS_H
@@ -50,6 +50,7 @@
 extern int num_threads;
 extern int live_threads;
 struct object;
+extern size_t thread_stack_size;
 extern struct object *thread_id;
 
 #define DEFINE_MUTEX(X) MUTEX_T X
@@ -117,7 +118,7 @@ extern pthread_attr_t small_pattr;
 
 #define th_setconcurrency(X) thr_setconcurrency(X)
 
-#define th_create(ID,fun,arg) thr_create(NULL,0,fun,arg,THR_DAEMON|THR_DETACHED,ID)
+#define th_create(ID,fun,arg) thr_create(NULL,thread_stack_size,fun,arg,THR_DAEMON|THR_DETACHED,ID)
 #define th_create_small(ID,fun,arg) thr_create(NULL,32768,fun,arg,THR_DAEMON|THR_DETACHED,ID)
 #define th_exit(foo) thr_exit(foo)
 #define th_self() thr_self()
@@ -281,6 +282,7 @@ struct thread_state {
   int mark_stack_malloced;
   JMP_BUF *recoveries;
   struct object * thread_id;
+  char *stack_top;
 #ifdef THREAD_TRACE
   int t_flag;
 #endif /* THREAD_TRACE */
@@ -332,6 +334,7 @@ struct thread_state {
        (_tmp)->mark_stack_malloced=mark_stack_malloced;\
        (_tmp)->recoveries=recoveries;\
        (_tmp)->sp=sp; \
+       (_tmp)->stack_top=stack_top; \
        (_tmp)->thread_id=thread_id;\
        SWAP_OUT_TRACE(_tmp); \
       } while(0)
@@ -346,6 +349,7 @@ struct thread_state {
        mark_stack_malloced=(_tmp)->mark_stack_malloced;\
        recoveries=(_tmp)->recoveries;\
        sp=(_tmp)->sp;\
+       stack_top=(_tmp)->stack_top;\
        thread_id=(_tmp)->thread_id;\
        SWAP_IN_TRACE(_tmp); \
      } while(0)
-- 
GitLab