diff --git a/src/error.c b/src/error.c
index f05aa5129b309e248d85d4c60ae22f32f2706339..517fc7d671a82930fa3fb22216168ed39da09161 100644
--- a/src/error.c
+++ b/src/error.c
@@ -17,8 +17,9 @@
 #include "backend.h"
 #include "operators.h"
 #include "module_support.h"
+#include "threads.h"
 
-RCSID("$Id: error.c,v 1.32 1999/04/02 15:18:05 hubbe Exp $");
+RCSID("$Id: error.c,v 1.33 1999/04/15 19:12:49 hubbe Exp $");
 
 #undef ATTRIBUTE
 #define ATTRIBUTE(X)
@@ -110,14 +111,25 @@ void push_error(char *description)
 
 struct svalue throw_value = { T_INT };
 int throw_severity;
-
 static const char *in_error;
+
+void low_error(char *buf)
+{
+  push_error(buf);
+  free_svalue(& throw_value);
+  throw_value = *--sp;
+  throw_severity=THROW_ERROR;
+  in_error=0;
+  pike_throw();  /* Hope someone is catching, or we will be out of balls. */
+}
+
 /* FIXME: NOTE: This function uses a static buffer.
  * Check sizes of arguments passed!
  */
 void va_error(const char *fmt, va_list args) ATTRIBUTE((noreturn))
 {
   char buf[4096];
+  SWAP_IN_THREAD_IF_REQUIRED();
   if(in_error)
   {
     const char *tmp=in_error;
@@ -146,13 +158,7 @@ void va_error(const char *fmt, va_list args) ATTRIBUTE((noreturn))
   if((long)strlen(buf) >= (long)sizeof(buf))
     fatal("Buffer overflow in error()\n");
   
-  push_error(buf);
-  free_svalue(& throw_value);
-  throw_value = *--sp;
-  throw_severity=THROW_ERROR;
-
-  in_error=0;
-  pike_throw();  /* Hope someone is catching, or we will be out of balls. */
+  low_error(buf);
 }
 
 void new_error(const char *name, const char *text, struct svalue *oldsp,
@@ -160,6 +166,8 @@ void new_error(const char *name, const char *text, struct svalue *oldsp,
 {
   int i;
 
+  ASSERT_THREAD_SWAPPED_IN();
+
   if(in_error)
   {
     const char *tmp=in_error;
@@ -320,8 +328,10 @@ void f_error_backtrace(INT32 args)
 
 #define INIT_ERROR(FEL)\
   va_list foo; \
-  struct object *o=low_clone(PIKE_CONCAT(FEL,_error_program)); \
-  va_start(foo,desc);
+  struct object *o; \
+  va_start(foo,desc); \
+  ASSERT_THREAD_SWAPPED_IN(); \
+  o=low_clone(PIKE_CONCAT(FEL,_error_program));
 
 #define ERROR_DONE(FOO) \
   PIKE_CONCAT(FOO,_error_va(o,func, \
diff --git a/src/interpret.h b/src/interpret.h
index 0ba39d0fc9133b04c0df6dfac873398e2ea32e3d..cd6454a1217ebed91a427403b825ca957d68ceb4 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: interpret.h,v 1.29 1999/04/12 20:00:37 grubba Exp $
+ * $Id: interpret.h,v 1.30 1999/04/15 19:12:50 hubbe Exp $
  */
 #ifndef INTERPRET_H
 #define INTERPRET_H
@@ -57,7 +57,7 @@ struct pike_frame
   long x_= ((char *)&x_) + STACK_DIRECTION * (X) - stack_top ;	\
   x_*=STACK_DIRECTION;							\
   if(x_>0)								\
-    error("C stack overflow.\n");					\
+    low_error("C stack overflow.\n");					\
   }while(0)
 
 
diff --git a/src/threads.h b/src/threads.h
index b67bb2aa5c391221dd3388eb4ff554dbb45e2656..674248e429ac685ec5f188a6770bb9c794a45488 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -1,5 +1,5 @@
 /*
- * $Id: threads.h,v 1.64 1999/04/07 23:10:12 hubbe Exp $
+ * $Id: threads.h,v 1.65 1999/04/15 19:12:51 hubbe Exp $
  */
 #ifndef THREADS_H
 #define THREADS_H
@@ -490,6 +490,21 @@ struct thread_state {
      } \
    } while(0)
 
+#define SWAP_IN_THREAD_IF_REQUIRED() do { 			\
+  struct thread_state *_tmp=thread_state_for_id(th_self());	\
+  HIDE_GLOBAL_VARIABLES();					\
+  THREADS_DISALLOW()
+
+#ifdef PIKE_DEBUG
+#define ASSERT_THREAD_SWAPPED_IN() do { 			\
+  struct thread_state *_tmp=thread_state_for_id(th_self());	\
+  if(_tmp->swapped) fatal("Thread is not swapped in!\n"); \
+  }while(0)
+
+#else
+#define ASSERT_THREAD_SWAPPED_IN()
+#endif
+
 /* Prototypes begin here */
 struct thread_starter;
 void *new_thread_func(void * data);
@@ -550,6 +565,8 @@ void exit_interleave_mutex(IMUTEX_T *im);
 #define THREADS_DISALLOW_UID()
 #define HIDE_GLOBAL_VARIABLES()
 #define REVEAL_GLOBAL_VARIABLES()
+#define ASSERT_THREAD_SWAPPED_IN()
+#define SWAP_IN_THREAD_IF_REQUIRED()
 #define th_init()
 #define low_th_init()
 #define th_cleanup()