Attaching the debugger to a running process should work again
(reported by Eric Pouech). Misc cleanups.

diff --git a/server/context_i386.c b/server/context_i386.c
index 75028cf..903f576 100644
--- a/server/context_i386.c
+++ b/server/context_i386.c
@@ -114,7 +114,7 @@
 /* retrieve a thread context */
 static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
 {
-    int pid = thread->unix_pid;
+    int pid = get_ptrace_pid(thread);
     if (flags & CONTEXT_FULL)
     {
         struct kernel_user_regs_struct regs;
@@ -170,7 +170,7 @@
 /* set a thread context */
 static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
 {
-    int pid = thread->unix_pid;
+    int pid = get_ptrace_pid(thread);
     if (flags & CONTEXT_FULL)
     {
         struct kernel_user_regs_struct regs;
@@ -230,7 +230,7 @@
 /* retrieve a thread context */
 static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
 {
-    int pid = thread->unix_pid;
+    int pid = get_ptrace_pid(thread);
     if (flags & CONTEXT_FULL)
     {
         struct regs regs;
@@ -281,7 +281,7 @@
 /* set a thread context */
 static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
 {
-    int pid = thread->unix_pid;
+    int pid = get_ptrace_pid(thread);
     if (flags & CONTEXT_FULL)
     {
         struct regs regs;
@@ -338,7 +338,7 @@
 /* retrieve a thread context */
 static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
 {
-    int pid = thread->unix_pid;
+    int pid = get_ptrace_pid(thread);
     if (flags & CONTEXT_FULL)
     {
         struct reg regs;
@@ -410,7 +410,7 @@
 /* set a thread context */
 static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
 {
-    int pid = thread->unix_pid;
+    int pid = get_ptrace_pid(thread);
     if (flags & CONTEXT_FULL)
     {
         struct reg regs;
diff --git a/server/context_powerpc.c b/server/context_powerpc.c
index b6a2598..3d86c3d 100644
--- a/server/context_powerpc.c
+++ b/server/context_powerpc.c
@@ -42,7 +42,7 @@
 /* retrieve a thread context */
 static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
 {
-    int pid = thread->unix_pid;
+    int pid = get_ptrace_pid(thread);
     if (flags & CONTEXT_FULL)
     {
         if (flags & CONTEXT_INTEGER)
@@ -117,7 +117,7 @@
 /* set a thread context */
 static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
 {
-    int pid = thread->unix_pid;
+    int pid = get_ptrace_pid(thread);
     if (flags & CONTEXT_FULL)
     {
         if (flags & CONTEXT_INTEGER)
diff --git a/server/context_sparc.c b/server/context_sparc.c
index 20b4a26..173c3f7 100644
--- a/server/context_sparc.c
+++ b/server/context_sparc.c
@@ -45,7 +45,7 @@
 /* retrieve a thread context */
 static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
 {
-    int pid = thread->unix_pid;
+    int pid = get_ptrace_pid(thread);
     if (flags & CONTEXT_FULL)
     {
         struct regs regs;
diff --git a/server/debugger.c b/server/debugger.c
index 0e9b875..29f92b2 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -429,20 +429,13 @@
         goto error;
 
     suspend_process( process );
-
-    /* we must have been able to attach all threads */
-    if (!process->thread_list) goto error2;
-    for (thread = process->thread_list; thread; thread = thread->proc_next)
+    if (!attach_process( process ) || !set_process_debugger( process, debugger ))
     {
-        if (!thread->attached) goto error2;
+        resume_process( process );
+        return 0;
     }
+    return 1;
 
-    if (set_process_debugger( process, debugger )) return 1;
-    resume_process( process );
-    return 0;
-
- error2:
-    resume_process( process );
  error:
     set_error( STATUS_ACCESS_DENIED );
     return 0;
@@ -452,7 +445,6 @@
 /* detach a process from a debugger thread (and resume it ?) */
 int debugger_detach( struct process *process, struct thread *debugger )
 {
-    struct thread *thread;
     struct debug_event *event;
     struct debug_ctx *debug_ctx;
 
@@ -488,15 +480,7 @@
     process->debugger = NULL;
     release_object( debugger->debug_ctx );
     debugger->debug_ctx = NULL;
-
-    /* now detach all the threads */
-    for (thread = process->thread_list; thread; thread = thread->proc_next)
-    {
-        if (thread->attached)
-        {
-            detach_thread( thread, 0 );
-        }
-    }
+    detach_process( process );
 
     /* from this function */
     resume_process( process );
diff --git a/server/process.c b/server/process.c
index 96482eb..9f26b8d 100644
--- a/server/process.c
+++ b/server/process.c
@@ -85,7 +85,7 @@
     int                 inherit_all;  /* inherit all handles from parent */
     int                 use_handles;  /* use stdio handles */
     int                 create_flags; /* creation flags */
-    pid_t               unix_pid;     /* Unix pid of new process */
+    int                 unix_pid;     /* Unix pid of new process */
     obj_handle_t        hstdin;       /* handle for stdin */
     obj_handle_t        hstdout;      /* handle for stdout */
     obj_handle_t        hstderr;      /* handle for stderr */
@@ -331,7 +331,7 @@
 }
 
 /* find the startup info for a given Unix process */
-inline static struct startup_info *find_startup_info( pid_t unix_pid )
+inline static struct startup_info *find_startup_info( int unix_pid )
 {
     struct list *ptr;
 
diff --git a/server/ptrace.c b/server/ptrace.c
index ae35c23..e2b19fc 100644
--- a/server/ptrace.c
+++ b/server/ptrace.c
@@ -123,7 +123,7 @@
 
     do
     {
-        if ((res = wait4( thread->unix_pid, &status, WUNTRACED, NULL )) == -1)
+        if ((res = wait4( get_ptrace_pid(thread), &status, WUNTRACED, NULL )) == -1)
         {
             if (errno == ECHILD)  /* must have died */
             {
@@ -137,6 +137,12 @@
     } while (res && res != signal);
 }
 
+/* return the Unix pid to use in ptrace calls for a given thread */
+int get_ptrace_pid( struct thread *thread )
+{
+    return thread->unix_pid;
+}
+
 /* send a Unix signal to a specific thread */
 int send_thread_signal( struct thread *thread, int sig )
 {
@@ -159,7 +165,7 @@
 {
     /* this may fail if the client is already being debugged */
     if (!use_ptrace) return 0;
-    if (ptrace( PTRACE_ATTACH, thread->unix_pid, 0, 0 ) == -1)
+    if (ptrace( PTRACE_ATTACH, get_ptrace_pid(thread), 0, 0 ) == -1)
     {
         if (errno == ESRCH) thread->unix_pid = -1;  /* thread got killed */
         return 0;
@@ -181,12 +187,43 @@
         if (sig) send_thread_signal( thread, sig );
         if (thread->unix_pid == -1) return;
         if (debug_level) fprintf( stderr, "%04x: *detached*\n", thread->id );
-        ptrace( PTRACE_DETACH, thread->unix_pid, (caddr_t)1, sig );
+        ptrace( PTRACE_DETACH, get_ptrace_pid(thread), (caddr_t)1, sig );
         thread->attached = 0;
     }
     else if (sig) send_thread_signal( thread, sig );
 }
 
+/* attach to a Unix process with ptrace */
+int attach_process( struct process *process )
+{
+    struct thread *thread;
+    int ret = 1;
+
+    if (!process->thread_list)  /* need at least one running thread */
+    {
+        set_error( STATUS_ACCESS_DENIED );
+        return 0;
+    }
+    for (thread = process->thread_list; thread; thread = thread->proc_next)
+    {
+        if (thread->attached) continue;
+        if (suspend_for_ptrace( thread )) resume_after_ptrace( thread );
+        else ret = 0;
+    }
+    return ret;
+}
+
+/* detach from a ptraced Unix process */
+void detach_process( struct process *process )
+{
+    struct thread *thread;
+
+    for (thread = process->thread_list; thread; thread = thread->proc_next)
+    {
+        if (thread->attached) detach_thread( thread, 0 );
+    }
+}
+
 /* suspend a thread to allow using ptrace on it */
 /* you must do a resume_after_ptrace when finished with the thread */
 int suspend_for_ptrace( struct thread *thread )
@@ -212,14 +249,14 @@
     if (thread->unix_pid == -1) return;
     assert( thread->attached );
     ptrace( get_thread_single_step(thread) ? PTRACE_SINGLESTEP : PTRACE_CONT,
-            thread->unix_pid, (caddr_t)1, 0 /* cancel the SIGSTOP */ );
+            get_ptrace_pid(thread), (caddr_t)1, 0 /* cancel the SIGSTOP */ );
 }
 
 /* read an int from a thread address space */
 int read_thread_int( struct thread *thread, const int *addr, int *data )
 {
     errno = 0;
-    *data = ptrace( PTRACE_PEEKDATA, thread->unix_pid, (caddr_t)addr, 0 );
+    *data = ptrace( PTRACE_PEEKDATA, get_ptrace_pid(thread), (caddr_t)addr, 0 );
     if ( *data == -1 && errno)
     {
         file_set_error();
@@ -237,7 +274,7 @@
         if (read_thread_int( thread, addr, &res ) == -1) return -1;
         data = (data & mask) | (res & ~mask);
     }
-    if ((res = ptrace( PTRACE_POKEDATA, thread->unix_pid, (caddr_t)addr, data )) == -1)
+    if ((res = ptrace( PTRACE_POKEDATA, get_ptrace_pid(thread), (caddr_t)addr, data )) == -1)
         file_set_error();
     return res;
 }
diff --git a/server/thread.h b/server/thread.h
index bf83f0c..8050d81 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -126,7 +126,10 @@
 /* ptrace functions */
 
 extern void sigchld_handler();
+extern int get_ptrace_pid( struct thread *thread );
 extern void detach_thread( struct thread *thread, int sig );
+extern int attach_process( struct process *process );
+extern void detach_process( struct process *process );
 extern int suspend_for_ptrace( struct thread *thread );
 extern void resume_after_ptrace( struct thread *thread );
 extern int read_thread_int( struct thread *thread, const int *addr, int *data );