Index: trunk/docs/Changelog
===================================================================
--- trunk/docs/Changelog	(revision 407)
+++ trunk/docs/Changelog	(revision 408)
@@ -1,3 +1,4 @@
 3.0.6:
+	* fix for --enable-ptrace: make the save_tv variable thread specific
 	* fix bug in inotify code which made it follow symlinks (by [anonymous])
 	* fix two missing SH_MUTEX_LOCK(mutex_thread_nolog) (by [anonymous])
Index: trunk/include/sh_unix.h
===================================================================
--- trunk/include/sh_unix.h	(revision 407)
+++ trunk/include/sh_unix.h	(revision 408)
@@ -374,5 +374,5 @@
 #endif
 #endif
-extern struct timeval  save_tv;
+void sh_set_save_tv();
 #endif
 
@@ -397,5 +397,5 @@
 
 #ifdef HAVE_GETTIMEOFDAY
-  gettimeofday(&save_tv, NULL);
+  sh_set_save_tv();
 #endif
 
Index: trunk/src/sh_pthread.c
===================================================================
--- trunk/src/sh_pthread.c	(revision 407)
+++ trunk/src/sh_pthread.c	(revision 408)
@@ -31,9 +31,9 @@
   int rc = 0;
 #ifdef SH_STEALTH
-  extern int sh_g_thread(void);
-
-  rc = sh_g_thread();
-  if (rc != 0)
-    return rc;
+  do {
+    extern int sh_g_thread(void);
+
+    rc = sh_g_thread();
+  } while (0);
 #endif
 
Index: trunk/src/sh_unix.c
===================================================================
--- trunk/src/sh_unix.c	(revision 407)
+++ trunk/src/sh_unix.c	(revision 408)
@@ -5401,5 +5401,66 @@
 
 #ifdef HAVE_GETTIMEOFDAY
-struct timeval  save_tv;
+
+#if defined(HAVE_PTHREAD)
+
+static pthread_key_t  gSaveTv_key;
+static pthread_once_t gSaveTv_key_once = PTHREAD_ONCE_INIT;
+
+static inline void make_gSaveTv_key()
+{
+    (void) pthread_key_create(&gSaveTv_key, free);
+}
+
+static inline struct timeval * sh_get_save_tv()
+{
+  void * ptr;
+  struct timeval * save_tv;
+
+  (void) pthread_once(&gSaveTv_key_once, make_gSaveTv_key);
+ 
+  if ((ptr = pthread_getspecific(gSaveTv_key)) == NULL) 
+    {
+      ptr = malloc(sizeof(struct timeval));
+      if (ptr)
+	{
+	  save_tv  = (struct timeval*) ptr;
+	  (void) pthread_setspecific(gSaveTv_key, ptr);
+	}
+      else
+	{
+	  return NULL;
+	}
+    }
+  else 
+    {
+      save_tv  = (struct timeval*) ptr;
+    }
+  return save_tv;
+}
+
+void sh_set_save_tv()
+{
+  struct timeval * save_tv = sh_get_save_tv();
+  if (save_tv)
+    gettimeofday(save_tv, NULL);
+  return;
+}
+
+/* !defined(HAVE_PTHREAD) */
+#else
+
+static struct timeval * sSaveTv = NULL;
+
+static inline struct timeval * sh_get_save_tv()
+{
+  return sSaveTv;
+}
+void sh_set_save_tv()
+{
+  gettimeofday(sSaveTv, NULL);
+}
+#endif
+
+/* #ifdef HAVE_GETTIMEOFDAY */
 #endif
 
@@ -5409,8 +5470,10 @@
   struct timeval  tv;
   long   difftv;
+  struct timeval * save_tv = sh_get_save_tv();
+
+  gettimeofday(&tv, NULL);
   
-  gettimeofday(&tv, NULL);
-  difftv = (tv.tv_sec - save_tv.tv_sec) * 1000000 + 
-    (tv.tv_usec - save_tv.tv_usec);
+  difftv = (tv.tv_sec - save_tv->tv_sec) * 1000000 + 
+    (tv.tv_usec - save_tv->tv_usec);
   if (difftv > 500000)
     raise(SIGKILL);
