diff -urNp linuxthreads-0.71-ORIG/internals.h linuxthreads-0.71/internals.h
--- linuxthreads-0.71-ORIG/internals.h	Fri Dec  5 01:28:20 1997
+++ linuxthreads-0.71/internals.h	Fri Nov 13 21:53:10 1998
@@ -95,7 +95,7 @@ struct pthread_handle_struct {
 struct pthread_request {
   pthread_descr req_thread;     /* Thread doing the request */
   enum {                        /* Request kind */
-    REQ_CREATE, REQ_FREE, REQ_PROCESS_EXIT, REQ_MAIN_THREAD_EXIT
+    REQ_CREATE, REQ_FREE, REQ_PROCESS_EXIT, REQ_MAIN_THREAD_EXIT, REQ_DEBUG
   } req_kind;
   union {                       /* Arguments for request */
     struct {                    /* For REQ_CREATE: */
@@ -243,6 +243,8 @@ static inline pthread_descr thread_self 
 #define ASSERT(x)
 #define MSG(msg,arg)
 #endif
+
+extern volatile int __pthread_threads_debug;
 
 /* Internal global functions */
 
diff -urNp linuxthreads-0.71-ORIG/manager.c linuxthreads-0.71/manager.c
--- linuxthreads-0.71-ORIG/manager.c	Mon Dec  1 01:48:51 1997
+++ linuxthreads-0.71/manager.c	Fri Nov 13 21:53:10 1998
@@ -37,6 +37,14 @@
 struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX] =
 { { 0, &__pthread_initial_thread}, /* All NULLs */ };
 
+/* # active entries in __pthread_handles array (used for library debugging) */
+
+volatile int __pthread_handles_num = 1;
+
+/* Use debugger additional actions for thread creation */
+
+volatile int __pthread_threads_debug = 0;
+
 /* Mapping from stack segment to thread descriptor. */
 /* Stack segment numbers are also indices into the __pthread_handles array. */
 /* Stack segment number 0 is reserved for the initial thread. */
@@ -86,10 +94,16 @@ int __pthread_manager(void * arg)
 #ifdef INIT_THREAD_SELF
   INIT_THREAD_SELF(&__pthread_manager_thread);
 #endif
-  /* Block all signals except PTHREAD_SIG_RESTART */
+  /* Block all signals except PTHREAD_SIG_RESTART, PTHREAD_SIG_CANCEL
+     and SIGTRAP */
   sigfillset(&mask);
   sigdelset(&mask, PTHREAD_SIG_RESTART);
+  sigdelset(&mask, PTHREAD_SIG_CANCEL);	/* for debugging new threads */
+  sigdelset(&mask, SIGTRAP);		/* for debugging purposes */
   sigprocmask(SIG_SETMASK, &mask, NULL);
+  /* Synchronize debugging of the thread manager */
+  n = __libc_read(reqfd, (char *)&request, sizeof(request));
+  ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG);
   /* Enter server loop */
   while(1) {
     FD_ZERO(&readfds);
@@ -136,6 +150,11 @@ int __pthread_manager(void * arg)
           return 0;
         }
         break;
+      case REQ_DEBUG:
+	if (__pthread_threads_debug)
+	  raise(PTHREAD_SIG_CANCEL); /* Make debugger aware of new thread */
+        restart(request.req_thread);
+        break;
       }
     }
   }
@@ -147,6 +166,7 @@ static int pthread_start_thread(void * a
 {
   pthread_descr self = (pthread_descr) arg;
   void * outcome;
+  struct pthread_request request;
   /* Initialize special thread_self processing, if any.  */
 #ifdef INIT_THREAD_SELF
   INIT_THREAD_SELF(self);
@@ -161,6 +181,13 @@ static int pthread_start_thread(void * a
   if (self->p_start_args.schedpolicy != SCHED_OTHER)
     __sched_setscheduler(self->p_pid, self->p_start_args.schedpolicy,
                          &self->p_start_args.schedparam);
+  /* Make debugger aware of new threads */
+  if (__pthread_threads_debug) {
+    request.req_thread = self;
+    request.req_kind = REQ_DEBUG;
+    __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
+    suspend(self);
+  }
   /* Run the thread code */
   outcome = self->p_start_args.start_routine(self->p_start_args.arg);
   /* Exit with the given return value */
@@ -191,6 +218,7 @@ static int pthread_handle_create(pthread
     /* It seems part of this segment is already mapped. Try the next. */
   }
   /* Allocate new thread identifier */
+  __pthread_handles_num++;
   pthread_threads_counter += PTHREAD_THREADS_MAX;
   new_thread_id = sseg + pthread_threads_counter;
   /* Initialize the thread descriptor */
@@ -248,6 +276,7 @@ static int pthread_handle_create(pthread
     munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
            INITIAL_STACK_SIZE);
     __pthread_handles[sseg].h_descr = NULL;
+    __pthread_handles_num--;
     return errno;
   }
   /* Insert new thread in doubly linked list of active threads */
@@ -274,6 +303,7 @@ static void pthread_free(pthread_descr t
   acquire(&handle->h_spinlock);
   handle->h_descr = NULL;
   release(&handle->h_spinlock);
+  __pthread_handles_num--;
   /* If initial thread, nothing to free */
   if (th == &__pthread_initial_thread) return;
   /* Free the stack and thread descriptor area */
diff -urNp linuxthreads-0.71-ORIG/pthread.c linuxthreads-0.71/pthread.c
--- linuxthreads-0.71-ORIG/pthread.c	Sun Nov 23 08:58:49 1997
+++ linuxthreads-0.71/pthread.c	Fri Nov 13 21:53:10 1998
@@ -119,6 +119,18 @@ char * __pthread_manager_thread_tos = NU
 int __pthread_exit_requested = 0;
 int __pthread_exit_code = 0;
 
+/* Internal values for library debugging future compatibility */
+
+const int __pthread_threads_max = PTHREAD_THREADS_MAX;
+const int __pthread_sig_restart = PTHREAD_SIG_RESTART;
+const int __pthread_sig_cancel = PTHREAD_SIG_CANCEL;
+
+const int __pthread_sizeof_handle = sizeof (struct pthread_handle_struct);
+const int __pthread_offsetof_descr = offsetof (struct pthread_handle_struct,
+					       h_descr);
+const int __pthread_offsetof_pid = offsetof (struct _pthread_descr_struct,
+					     p_pid);
+
 /* Forward declarations */
 
 static void pthread_exit_process(int retcode, void * arg);
@@ -205,6 +217,8 @@ static int pthread_initialize_manager(vo
     __pthread_manager_request = -1;
     return -1;
   }
+  /* Set pid field of the thread manager. */
+  __pthread_manager_thread.p_pid = __pthread_manager_pid;
   return 0;
 }
 
@@ -216,7 +230,14 @@ int pthread_create(pthread_t *thread, co
   pthread_descr self = thread_self();
   struct pthread_request request;
   if (__pthread_manager_request < 0) {
-    if (pthread_initialize_manager() < 0) return EAGAIN;
+    if (pthread_initialize_manager() < 0)
+      return EAGAIN;
+    if (__pthread_threads_debug)
+      raise(PTHREAD_SIG_CANCEL); /* Make debugger aware of new thread manager */
+    /* Synchronize debugging of the thread manager */
+    request.req_thread = self;
+    request.req_kind = REQ_DEBUG;
+    __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
   }
   request.req_thread = self;
   request.req_kind = REQ_CREATE;
@@ -325,13 +346,24 @@ void __pthread_sighandler(int sig)
 }
 
 /* The handler for the CANCEL signal checks for cancellation
-   (in asynchronous mode) and for process-wide exit and exec requests. */
+   (in asynchronous mode), for process-wide exit, exec requests
+   and for new thread debugging. */
 
 static void pthread_handle_sigcancel(int sig)
 {
   pthread_descr self = thread_self();
   sigjmp_buf * jmpbuf;
 
+  if (self == &__pthread_manager_thread) {
+    /* On reception of a REQ_DEBUG request (sent by new threads created to
+       the thread manager under debugging mode), the thread manager throws
+       PTHREAD_SIG_CANCEL to itself. The debugger (if active) intercepts
+       this signal, takes into account new threads and continue execution
+       of the thread manager by propagating the signal because it doesn't
+       know what it is specifically done for. In the current implementation,
+       the thread manager simply discards it. */
+    return;
+  }
   if (__pthread_exit_requested) {
     /* Main thread should accumulate times for thread manager and its
        children, so that timings for main thread account for all threads. */

