diff --git a/src/backend.c b/src/backend.c
index a182f5fb8182fa98108e0ebceeaafce66fda1a82..aacc1970c2b29775a669ba92a31ae5ae9ad5a279 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: backend.c,v 1.59 2000/10/04 22:36:18 grubba Exp $");
+RCSID("$Id: backend.c,v 1.60 2000/11/20 01:20:24 mast Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include <errno.h>
@@ -722,17 +722,11 @@ void backend(void)
 
   if(SETJMP(back))
   {
-    ONERROR tmp;
-    t_flag=0;
-    SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
-    *(sp++)=throw_value;
+    call_handle_error();
+    free_svalue(&throw_value);
     throw_value.type=T_INT;
     throw_value.subtype=NUMBER_UNDEFINED;
     throw_value.u.integer=0;
-
-    APPLY_MASTER("handle_error", 1);
-    pop_stack();
-    UNSET_ONERROR(tmp);
   }
 
   while(first_object)
diff --git a/src/interpret.c b/src/interpret.c
index a57c78bd83d6997d495cf98040dabce405a4db3a..ca18156dbd86d8d7200b37edad9a5a2fd5e69c57 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.172 2000/10/01 08:51:52 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.173 2000/11/20 01:20:24 mast Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -58,6 +58,11 @@ RCSID("$Id: interpret.c,v 1.172 2000/10/01 08:51:52 hubbe Exp $");
 
 #define TRACE_LEN (100 + t_flag * 10)
 
+/* Keep some margin on the stack space checks. They're lifted when
+ * handle_error runs to give it some room. */
+#define SVALUE_STACK_MARGIN 100	/* Tested in 7.1: 40 was enough, 30 wasn't. */
+#define C_STACK_MARGIN 2000	/* Tested in 7.1: 1500 was enough, 1400 wasn't. */
+
 
 #ifdef PIKE_DEBUG
 static char trace_buffer[2000];
@@ -177,6 +182,9 @@ use_malloc:
   Pike_mark_sp=Pike_interpreter.mark_stack;
   Pike_fp=0;
 
+  Pike_interpreter.svalue_stack_margin = SVALUE_STACK_MARGIN;
+  Pike_interpreter.c_stack_margin = C_STACK_MARGIN;
+
 #ifdef PIKE_DEBUG
   {
     static struct callback *spcb;
@@ -1431,6 +1439,25 @@ PMOD_EXPORT void f_call_function(INT32 args)
   mega_apply(APPLY_STACK,args,0,0);
 }
 
+PMOD_EXPORT void call_handle_error(void)
+{
+  if (Pike_interpreter.svalue_stack_margin) {
+    ONERROR tmp;
+    int old_t_flag = t_flag;
+    t_flag = 0;
+    Pike_interpreter.svalue_stack_margin = 0;
+    Pike_interpreter.c_stack_margin = 0;
+    SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
+    assign_svalue_no_free(Pike_sp++, & throw_value);
+    APPLY_MASTER("handle_error", 1);
+    pop_stack();
+    UNSET_ONERROR(tmp);
+    Pike_interpreter.svalue_stack_margin = SVALUE_STACK_MARGIN;
+    Pike_interpreter.c_stack_margin = C_STACK_MARGIN;
+    t_flag = old_t_flag;
+  }
+}
+
 PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset)
 {
   JMP_BUF tmp;
@@ -1486,22 +1513,7 @@ PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args)
   if(SETJMP(recovery))
   {
     if(throw_value.type == T_ARRAY)
-    {
-      static int inside=0;
-      if(!inside)
-      {
-	ONERROR tmp;
-	/* We silently ignore errors if we are already describing one.. */
-	inside=1;
-	SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
-	assign_svalue_no_free(Pike_sp++, & throw_value);
-	APPLY_MASTER("handle_error", 1);
-	pop_stack();
-	UNSET_ONERROR(tmp);
-	inside=0;
-      }
-    }
-      
+      call_handle_error();
     Pike_sp->u.integer = 0;
     Pike_sp->subtype=NUMBER_NUMBER;
     Pike_sp->type = T_INT;
diff --git a/src/interpret.h b/src/interpret.h
index 6b52e670e93d26e38f62e9e8f1a178af026e3ac8..4e7c346f1defa5e29fbb4a065c08ae20adddc08e 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: interpret.h,v 1.67 2000/09/12 17:06:08 grubba Exp $
+ * $Id: interpret.h,v 1.68 2000/11/20 01:20:24 mast Exp $
  */
 #ifndef INTERPRET_H
 #define INTERPRET_H
@@ -30,6 +30,9 @@ struct Pike_interpreter {
   char *stack_top;
   DO_IF_SECURITY(struct object *current_creds;)
 
+  int svalue_stack_margin;
+  int c_stack_margin;
+
 #ifdef PROFILING
 #ifdef HAVE_GETHRTIME
   long long accounted_time;
@@ -80,7 +83,8 @@ struct external_variable_context
 #endif
 
 #define check_stack(X) do { \
-  if(Pike_sp - Pike_interpreter.evaluator_stack + (X) >= Pike_stack_size) \
+  if(Pike_sp - Pike_interpreter.evaluator_stack + \
+     Pike_interpreter.svalue_stack_margin + (X) >= Pike_stack_size) \
     error("Svalue stack overflow. " \
 	  "(%ld of %ld entries on stack, needed %ld more entries)\n", \
 	  PTRDIFF_T_TO_LONG(Pike_sp - Pike_interpreter.evaluator_stack), \
@@ -93,8 +97,10 @@ struct external_variable_context
     error("Mark stack overflow.\n");		\
   }while(0)
 
-#define check_c_stack(X) do { 			\
-  ptrdiff_t x_= ((char *)&x_) + STACK_DIRECTION * (X) - Pike_interpreter.stack_top ;	\
+#define check_c_stack(X) do {						\
+  ptrdiff_t x_= ((char *)&x_) +						\
+    STACK_DIRECTION * (Pike_interpreter.c_stack_margin + (X)) -		\
+    Pike_interpreter.stack_top ;					\
   x_*=STACK_DIRECTION;							\
   if(x_>0)								\
     low_error("C stack overflow.\n");					\
@@ -246,6 +252,7 @@ PMOD_EXPORT void find_external_context(struct external_variable_context *loc,
 				       int arg2);
 PMOD_EXPORT void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
 PMOD_EXPORT void f_call_function(INT32 args);
+PMOD_EXPORT void call_handle_error(void);
 PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset);
 PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args);
 PMOD_EXPORT void safe_apply(struct object *o, char *fun ,INT32 args);
diff --git a/src/las.c b/src/las.c
index 86e7e20ed9a7e3c6756497e21f635381bc210c88..4e14ad1eba305a2bd1b7d5c181187f82ef4d024e 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.221 2000/10/03 18:18:29 grubba Exp $");
+RCSID("$Id: las.c,v 1.222 2000/11/20 01:20:25 mast Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -1517,15 +1517,10 @@ node *index_node(node *n, char *node_name, struct pike_string *id)
 
   if(SETJMP(tmp))
   {
-    ONERROR tmp;
     struct svalue s;
 
-    SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
-    assign_svalue_no_free(Pike_sp++, &throw_value);
     assign_svalue_no_free(&s, &throw_value);
-    APPLY_MASTER("handle_error", 1);
-    pop_stack();
-    UNSET_ONERROR(tmp);
+    call_handle_error();
 
     if (node_name) {
       my_yyerror("Couldn't index module '%s'.", node_name);
diff --git a/src/main.c b/src/main.c
index 4280f5d22570e0bd2fa0a7a9e67eaaad0dee42a3..8ab70d1fe397b7cb42dbc0bc80236ee77d4edec9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: main.c,v 1.106 2000/11/06 17:03:32 grubba Exp $");
+RCSID("$Id: main.c,v 1.107 2000/11/20 01:20:25 mast Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include "module.h"
@@ -534,13 +534,7 @@ int dbm_main(int argc, char **argv)
     {
       num=throw_value.u.integer;
     }else{
-      ONERROR tmp;
-      t_flag=0;
-      SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
-      push_svalue(& throw_value);
-      APPLY_MASTER("handle_error", 1);
-      pop_stack();
-      UNSET_ONERROR(tmp);
+      call_handle_error();
       num=10;
     }
   }else{
diff --git a/src/program.c b/src/program.c
index a336149af0babf30878ad87185a7c146b839d07b..b1d4f72e6d84a4d6f9ebe25922d4b11461f12218 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.281 2000/11/08 22:21:32 hubbe Exp $");
+RCSID("$Id: program.c,v 1.282 2000/11/20 01:20:25 mast Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -305,13 +305,7 @@ static struct node_s *index_modules(struct pike_string *ident,
 
     if(SETJMP(tmp))
     {
-      ONERROR tmp2;
-      SET_ONERROR(tmp2, exit_on_error,
-		  "Error in handle_error in master object!");
-      assign_svalue_no_free(Pike_sp++, &throw_value);
-      APPLY_MASTER("handle_error", 1);
-      pop_stack();
-      UNSET_ONERROR(tmp2);
+      call_handle_error();
       yyerror("Couldn't index module.");
     } else {
       int e = num_used_modules;
@@ -2996,14 +2990,9 @@ int store_constant(struct svalue *foo,
 
   if(SETJMP(tmp2))
   {
-    ONERROR tmp;
     struct svalue zero;
 
-    SET_ONERROR(tmp,exit_on_error,"Error in store_constant in compiler!");
-    assign_svalue_no_free(Pike_sp++, & throw_value);
-    APPLY_MASTER("handle_error", 1);
-    pop_stack();
-    UNSET_ONERROR(tmp);
+    call_handle_error();
 
     yyerror("Couldn't store constant.");
 
diff --git a/src/threads.c b/src/threads.c
index dd70fb64d986236dbc0e1850c61433aafdbda3fa..44613ba0324f22959ae61d56a1e1d184786f1f77 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.144 2000/11/06 19:29:17 mast Exp $");
+RCSID("$Id: threads.c,v 1.145 2000/11/20 01:20:26 mast Exp $");
 
 PMOD_EXPORT int num_threads = 1;
 PMOD_EXPORT int threads_disabled = 0;
@@ -621,15 +621,7 @@ TH_RETURN_TYPE new_thread_func(void * data)
   if(SETJMP(back))
   {
     if(throw_severity < THROW_EXIT)
-    {
-      ONERROR tmp;
-      t_flag=0;
-      SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
-      assign_svalue_no_free(Pike_sp++, & throw_value);
-      APPLY_MASTER("handle_error", 1);
-      pop_stack();
-      UNSET_ONERROR(tmp);
-    }
+      call_handle_error();
     if(throw_severity == THROW_EXIT)
     {
       free((char *) data);