Have threads and processes exit more cleanly whenever possible.

diff --git a/include/server.h b/include/server.h
index ffb014b..f6031d4 100644
--- a/include/server.h
+++ b/include/server.h
@@ -191,6 +191,7 @@
 {
     IN  int          handle;       /* process handle to terminate */
     IN  int          exit_code;    /* process exit code */
+    OUT int          self;         /* suicide? */
 };
 
 
@@ -199,6 +200,8 @@
 {
     IN  int          handle;       /* thread handle to terminate */
     IN  int          exit_code;    /* thread exit code */
+    OUT int          self;         /* suicide? */
+    OUT int          last;         /* last thread in this process? */
 };
 
 
@@ -1202,7 +1205,7 @@
     REQ_NB_REQUESTS
 };
 
-#define SERVER_PROTOCOL_VERSION 3
+#define SERVER_PROTOCOL_VERSION 4
 
 /* ### make_requests end ### */
 /* Everything above this line is generated automatically by tools/make_requests */
@@ -1219,7 +1222,7 @@
 
 extern unsigned int server_call_noerr( enum request req );
 extern unsigned int server_call_fd( enum request req, int fd_out, int *fd_in );
-extern void server_protocol_error( const char *err, ... );
+extern void server_protocol_error( const char *err, ... ) WINE_NORETURN;
 
 /* get a pointer to the request buffer */
 static inline void * WINE_UNUSED get_req_buffer(void)
diff --git a/include/thread.h b/include/thread.h
index 88ffd4b..c59aab4 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -131,6 +131,6 @@
 /* scheduler/sysdeps.c */
 extern int SYSDEPS_SpawnThread( TEB *teb );
 extern void SYSDEPS_SetCurThread( TEB *teb );
-extern void SYSDEPS_ExitThread(void);
+extern void SYSDEPS_ExitThread( int status ) WINE_NORETURN;
 
 #endif  /* __WINE_THREAD_H */
diff --git a/include/winbase.h b/include/winbase.h
index 467fa8a..ad89002 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1223,8 +1223,8 @@
 #define     EnumTimeFormats WINELIB_NAME_AW(EnumTimeFormats)
 BOOL        WINAPI EqualSid(PSID, PSID);
 BOOL        WINAPI EqualPrefixSid(PSID,PSID);
-VOID        WINAPI ExitProcess(DWORD);
-VOID        WINAPI ExitThread(DWORD);
+VOID        WINAPI ExitProcess(DWORD) WINE_NORETURN;
+VOID        WINAPI ExitThread(DWORD) WINE_NORETURN;
 DWORD       WINAPI ExpandEnvironmentStringsA(LPCSTR,LPSTR,DWORD);
 DWORD       WINAPI ExpandEnvironmentStringsW(LPCWSTR,LPWSTR,DWORD);
 #define     ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings)
diff --git a/include/windef.h b/include/windef.h
index 6a5c9db..f6a69b4 100644
--- a/include/windef.h
+++ b/include/windef.h
@@ -353,11 +353,13 @@
 /* Macro for structure packing. */
 
 #ifdef __GNUC__
-#define WINE_PACKED __attribute__ ((packed))
-#define WINE_UNUSED __attribute__ ((unused))
+#define WINE_PACKED   __attribute__((packed))
+#define WINE_UNUSED   __attribute__((unused))
+#define WINE_NORETURN __attribute__((noreturn))
 #else
-#define WINE_PACKED  /* nothing */
-#define WINE_UNUSED  /* nothing */
+#define WINE_PACKED    /* nothing */
+#define WINE_UNUSED    /* nothing */
+#define WINE_NORETURN  /* nothing */
 #endif
 
 /* Macros to split words and longs. */
diff --git a/loader/module.c b/loader/module.c
index ea528f4..6380919 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -221,14 +221,13 @@
  * Send DLL process detach notifications.  See the comment about calling 
  * sequence at MODULE_DllProcessAttach.  Unless the bForceDetach flag
  * is set, only DLLs with zero refcount are notified.
- *
- * NOTE: Assumes that the process critical section is held!
- *
  */
 void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
 {
     WINE_MODREF *wm;
 
+    EnterCriticalSection( &PROCESS_Current()->crit_section );
+
     do
     {
         for ( wm = PROCESS_Current()->modref_list; wm; wm = wm->next )
@@ -248,6 +247,8 @@
             break;
         }
     } while ( wm );
+
+    LeaveCriticalSection( &PROCESS_Current()->crit_section );
 }
 
 /*************************************************************************
diff --git a/scheduler/client.c b/scheduler/client.c
index 1215725..6767416 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -78,17 +78,6 @@
 }
 
 /***********************************************************************
- *           CLIENT_Die
- *
- * Die on protocol errors or socket close
- */
-static void CLIENT_Die(void)
-{
-    close( NtCurrentTeb()->socket );
-    SYSDEPS_ExitThread();
-}
-
-/***********************************************************************
  *           server_protocol_error
  */
 void server_protocol_error( const char *err, ... )
@@ -99,7 +88,7 @@
     fprintf( stderr, "Client protocol error:%p: ", NtCurrentTeb()->tid );
     vfprintf( stderr, err, args );
     va_end( args );
-    CLIENT_Die();
+    SYSDEPS_ExitThread(1);
 }
 
 
@@ -110,7 +99,7 @@
 {
     fprintf( stderr, "Client protocol error:%p: ", NtCurrentTeb()->tid );
     perror( err );
-    CLIENT_Die();
+    SYSDEPS_ExitThread(1);
 }
 
 
@@ -126,7 +115,7 @@
         return;
     if (ret == -1)
     {
-        if (errno == EPIPE) CLIENT_Die();
+        if (errno == EPIPE) SYSDEPS_ExitThread(0);
         server_perror( "sendmsg" );
     }
     server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
@@ -170,7 +159,7 @@
     if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(req)) return;
     if (ret == -1)
     {
-        if (errno == EPIPE) CLIENT_Die();
+        if (errno == EPIPE) SYSDEPS_ExitThread(0);
         server_perror( "sendmsg" );
     }
     server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
@@ -190,15 +179,17 @@
     {
         if ((ret = read( NtCurrentTeb()->socket, &res, sizeof(res) )) == sizeof(res))
             return res;
+        if (!ret) break;
         if (ret == -1)
         {
             if (errno == EINTR) continue;
-            if (errno == EPIPE) CLIENT_Die();
+            if (errno == EPIPE) break;
             server_perror("read");
         }
-        if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */
         server_protocol_error( "partial msg received %d/%d\n", ret, sizeof(res) );
     }
+    /* the server closed the connection; time to die... */
+    SYSDEPS_ExitThread(0);
 }
 
 
@@ -248,15 +239,17 @@
 #endif
             return res;
         }
+        if (!ret) break;
         if (ret == -1)
         {
             if (errno == EINTR) continue;
-            if (errno == EPIPE) CLIENT_Die();
+            if (errno == EPIPE) break;
             server_perror("recvmsg");
         }
-        if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */
         server_protocol_error( "partial seq received %d/%d\n", ret, sizeof(res) );
     }
+    /* the server closed the connection; time to die... */
+    SYSDEPS_ExitThread(0);
 }
 
 
diff --git a/scheduler/process.c b/scheduler/process.c
index ec41917..a783790 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -627,12 +627,16 @@
  */
 void WINAPI ExitProcess( DWORD status )
 {
-    EnterCriticalSection( &PROCESS_Current()->crit_section );
-    MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
-    LeaveCriticalSection( &PROCESS_Current()->crit_section );
+    struct terminate_process_request *req = get_req_buffer();
 
+    MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
     TASK_KillTask( 0 );
-    TerminateProcess( GetCurrentProcess(), status );
+
+    /* send the exit code to the server */
+    req->handle    = GetCurrentProcess();
+    req->exit_code = status;
+    server_call( REQ_TERMINATE_PROCESS );
+    exit( status );
 }
 
 /***********************************************************************
@@ -649,10 +653,12 @@
  */
 BOOL WINAPI TerminateProcess( HANDLE handle, DWORD exit_code )
 {
+    BOOL ret;
     struct terminate_process_request *req = get_req_buffer();
     req->handle    = handle;
     req->exit_code = exit_code;
-    return !server_call( REQ_TERMINATE_PROCESS );
+    if ((ret = !server_call( REQ_TERMINATE_PROCESS )) && req->self) exit( exit_code );
+    return ret;
 }
 
 
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index 684357b..559e4a9 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -137,7 +137,7 @@
         TerminateThread( GetCurrentThread(), GetExceptionCode() );
     }
     __ENDTRY
-    SYSDEPS_ExitThread();  /* should never get here */
+    SYSDEPS_ExitThread(0);  /* should never get here */
 }
 
 
@@ -153,31 +153,31 @@
 
 #ifdef linux
     if (clone( (int (*)(void *))SYSDEPS_StartThread, teb->stack_top,
-               CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, teb ) < 0)
+               CLONE_VM | CLONE_FS | SIGCHLD, teb ) < 0)
         return -1;
-    /* FIXME: close the child socket in the parent process */
-/*    close( thread->socket );*/
+    close( teb->socket );  /* close the child socket in the parent */
     return 0;
 #endif
 
 #ifdef HAVE_RFORK
-    DWORD *sp = (DWORD *)teb->stack_top;
-    *--sp = (DWORD)teb;
+    void **sp = (void **)teb->stack_top;
+    *--sp = teb;
     *--sp = 0;
-    *--sp = (DWORD)SYSDEPS_StartThread;
-    __asm__(
-    "pushl %2;\n\t"		/* RFPROC|RMEM */
+    *--sp = SYSDEPS_StartThread;
+    __asm__ __volatile__(
+    "pushl %2;\n\t"		/* RFPROC|RFMEM|RFFDG */
     "pushl $0;\n\t"		/* 0 ? */
     "movl %1,%%eax;\n\t"	/* SYS_rfork */
     ".byte 0x9a; .long 0; .word 7;\n\t"	/* lcall 7:0... FreeBSD syscall */
     "cmpl $0, %%edx;\n\t"
     "je 1f;\n\t"
-    "movl %0,%%esp;\n\t"	/* father -> new thread */
+    "movl %0,%%esp;\n\t"	/* child -> new thread */
     "ret;\n"
-    "1:\n\t"		/* child -> caller thread */
+    "1:\n\t"		/* parent -> caller thread */
     "addl $8,%%esp" :
-    : "r" (sp), "g" (SYS_rfork), "g" (RFPROC|RFMEM)
+    : "r" (sp), "g" (SYS_rfork), "g" (RFPROC|RFMEM|RFFDG)
     : "eax", "edx");
+    close( teb->socket );  /* close the child socket in the parent */
     return 0;
 #endif
 
@@ -202,15 +202,14 @@
  *           SYSDEPS_ExitThread
  *
  * Exit a running thread; must not return.
- * Must not make any reference to the thread structures (THDB etc.) as
- * they have already been deleted.
  */
-void SYSDEPS_ExitThread(void)
+void SYSDEPS_ExitThread( int status )
 {
-#if !defined(__i386__) && defined(HAVE__LWP_CREATE)
+#ifdef HAVE__LWP_CREATE
+    close( NtCurrentTeb()->socket );
     _lwp_exit();
 #endif
-    _exit( 0 );
+    _exit( status );
 }
 
 
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 9082cb8..a0c7391 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -336,8 +336,23 @@
  */
 void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
 {
-    MODULE_DllThreadDetach( NULL );
-    TerminateThread( GetCurrentThread(), code );
+    struct terminate_thread_request *req = get_req_buffer();
+
+     /* send the exit code to the server */
+    req->handle    = GetCurrentThread();
+    req->exit_code = code;
+    server_call( REQ_TERMINATE_THREAD );
+    if (req->last)
+    {
+        MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
+        TASK_KillTask( 0 );
+        exit( code );
+    }
+    else
+    {
+        MODULE_DllThreadDetach( NULL );
+        SYSDEPS_ExitThread( code );
+    }
 }
 
 
@@ -590,10 +605,16 @@
     HANDLE handle, /* [in] Handle to thread */
     DWORD exitcode)  /* [in] Exit code for thread */
 {
+    BOOL ret;
     struct terminate_thread_request *req = get_req_buffer();
     req->handle    = handle;
     req->exit_code = exitcode;
-    return !server_call( REQ_TERMINATE_THREAD );
+    if ((ret = !server_call( REQ_TERMINATE_THREAD )) && req->self)
+    {
+        if (req->last) exit( exitcode );
+        else SYSDEPS_ExitThread( exitcode );
+    }
+    return ret;
 }
 
 
diff --git a/server/process.c b/server/process.c
index 8073e55..07b2a0a 100644
--- a/server/process.c
+++ b/server/process.c
@@ -399,10 +399,16 @@
 }
 
 /* kill a process on the spot */
-void kill_process( struct process *process, int exit_code )
+static void kill_process( struct process *process, struct thread *skip, int exit_code )
 {
-    while (process->thread_list)
-        kill_thread( process->thread_list, exit_code );
+    struct thread *thread = process->thread_list;
+    while (thread)
+    {
+        struct thread *next = thread->proc_next;
+        thread->exit_code = exit_code;
+        if (thread != skip) kill_thread( thread, 1 );
+        thread = next;
+    }
 }
 
 /* kill all processes being debugged by a given thread */
@@ -416,7 +422,7 @@
             process = process->next;
         if (!process) return;
         process->debugger = NULL;
-        kill_process( process, exit_code );
+        kill_process( process, NULL, exit_code );
     }
 }
 
@@ -678,7 +684,8 @@
 
     if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
     {
-        kill_process( process, req->exit_code );
+        req->self = (current->process == process);
+        kill_process( process, current, req->exit_code );
         release_object( process );
     }
 }
diff --git a/server/process.h b/server/process.h
index 9f21e05..6cdbb6a 100644
--- a/server/process.h
+++ b/server/process.h
@@ -73,7 +73,6 @@
                                    struct thread *thread );
 extern void suspend_process( struct process *process );
 extern void resume_process( struct process *process );
-extern void kill_process( struct process *process, int exit_code );
 extern void kill_debugged_processes( struct thread *debugger, int exit_code );
 extern struct process_snapshot *process_snap( int *count );
 
diff --git a/server/ptrace.c b/server/ptrace.c
index 9cd4c04..0346e72 100644
--- a/server/ptrace.c
+++ b/server/ptrace.c
@@ -117,21 +117,21 @@
 }
 
 /* detach from a Unix thread and kill it */
-void detach_thread( struct thread *thread )
+void detach_thread( struct thread *thread, int sig )
 {
     if (!thread->unix_pid) return;
     if (thread->attached)
     {
         /* make sure it is stopped */
         if (!(thread->suspend + thread->process->suspend)) stop_thread( thread );
-        kill( thread->unix_pid, SIGTERM );
+        if (sig) kill( thread->unix_pid, sig );
         if (debug_level) fprintf( stderr, "%08x: *detached*\n", (unsigned int)thread );
-        ptrace( PTRACE_DETACH, thread->unix_pid, 1, SIGTERM );
+        ptrace( PTRACE_DETACH, thread->unix_pid, 1, sig );
         thread->attached = 0;
     }
     else
     {
-        kill( thread->unix_pid, SIGTERM );
+        if (sig) kill( thread->unix_pid, sig );
         if (thread->suspend + thread->process->suspend) continue_thread( thread );
     }
 }
diff --git a/server/request.c b/server/request.c
index 582f839..011124c 100644
--- a/server/request.c
+++ b/server/request.c
@@ -98,7 +98,8 @@
     fprintf( stderr, "Protocol error:%p: ", thread );
     vfprintf( stderr, err, args );
     va_end( args );
-    kill_thread( thread, PROTOCOL_ERROR );
+    thread->exit_code = 1;
+    kill_thread( thread, 1 );
 }
 
 /* die on a fatal error */
@@ -193,12 +194,13 @@
     if (ret == -1)
     {
         perror("recvmsg");
-        kill_thread( thread, BROKEN_PIPE );
+        thread->exit_code = 1;
+        kill_thread( thread, 1 );
         return;
     }
     if (!ret)  /* closed pipe */
     {
-        kill_thread( thread, BROKEN_PIPE );
+        kill_thread( thread, 0 );
         return;
     }
     fatal_protocol_error( thread, "partial message received %d/%d\n", ret, sizeof(req) );
@@ -212,7 +214,6 @@
     if (thread->pass_fd == -1)
     {
         ret = write( thread->obj.fd, &thread->error, sizeof(thread->error) );
-        if (ret == sizeof(thread->error)) goto ok;
     }
     else  /* we have an fd to send */
     {
@@ -231,20 +232,33 @@
         ret = sendmsg( thread->obj.fd, &msghdr, 0 );
         close( thread->pass_fd );
         thread->pass_fd = -1;
-        if (ret == sizeof(thread->error)) goto ok;
+    }
+    if (ret == sizeof(thread->error))
+    {
+        set_select_events( &thread->obj, POLLIN );
+        return 1;
     }
     if (ret == -1)
     {
         if (errno == EWOULDBLOCK) return 0;  /* not a fatal error */
-        if (errno != EPIPE) perror("sendmsg");
+        if (errno == EPIPE)
+        {
+            kill_thread( thread, 0 );  /* normal death */
+        }
+        else
+        {
+            perror("sendmsg");
+            thread->exit_code = 1;
+            kill_thread( thread, 1 );
+        }
     }
-    else fprintf( stderr, "Partial message sent %d/%d\n", ret, sizeof(thread->error) );
-    kill_thread( thread, BROKEN_PIPE );
+    else
+    {
+        thread->exit_code = 1;
+        kill_thread( thread, 1 );
+        fprintf( stderr, "Partial message sent %d/%d\n", ret, sizeof(thread->error) );
+    }
     return -1;
-
- ok:
-    set_select_events( &thread->obj, POLLIN );
-    return 1;
 }
 
 static void master_socket_dump( struct object *obj, int verbose )
diff --git a/server/request.h b/server/request.h
index a907747..3e746db 100644
--- a/server/request.h
+++ b/server/request.h
@@ -16,11 +16,6 @@
 /* max request length */
 #define MAX_REQUEST_LENGTH  8192
 
-/* exit code passed to remove_client on communication error */
-#define OUT_OF_MEMORY  -1
-#define BROKEN_PIPE    -2
-#define PROTOCOL_ERROR -3
-
 /* request handler definition */
 #define DECL_HANDLER(name) void req_##name( struct name##_request *req )
 
diff --git a/server/thread.c b/server/thread.c
index e82c4a7..eef39df 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -137,7 +137,7 @@
     thread->pass_fd     = -1;
     thread->state       = RUNNING;
     thread->attached    = 0;
-    thread->exit_code   = STILL_ACTIVE;
+    thread->exit_code   = 0;
     thread->next        = NULL;
     thread->prev        = NULL;
     thread->priority    = THREAD_PRIORITY_NORMAL;
@@ -175,7 +175,7 @@
     struct thread *thread = (struct thread *)obj;
     assert( obj->ops == &thread_ops );
 
-    if (event & (POLLERR | POLLHUP)) kill_thread( thread, BROKEN_PIPE );
+    if (event & (POLLERR | POLLHUP)) kill_thread( thread, 0 );
     else
     {
         if (event & POLLOUT) write_request( thread );
@@ -556,20 +556,25 @@
 }
 
 /* kill a thread on the spot */
-void kill_thread( struct thread *thread, int exit_code )
+void kill_thread( struct thread *thread, int violent_death )
 {
     if (thread->state == TERMINATED) return;  /* already killed */
     thread->state = TERMINATED;
-    thread->exit_code = exit_code;
     if (current == thread) current = NULL;
     if (debug_level)
-        fprintf( stderr,"%08x: *killed* exit_code=%d\n", (unsigned int)thread, exit_code );
-    if (thread->wait) end_wait( thread );
+        fprintf( stderr,"%08x: *killed* exit_code=%d\n",
+                 (unsigned int)thread, thread->exit_code );
+    if (thread->wait)
+    {
+        end_wait( thread );
+        /* if it is waiting on the socket, we don't need to send a SIGTERM */
+        violent_death = 0;
+    }
     debug_exit_thread( thread );
     abandon_mutexes( thread );
     remove_process_thread( thread->process, thread );
     wake_up( &thread->obj, 0 );
-    detach_thread( thread );
+    detach_thread( thread, violent_death ? SIGTERM : 0 );
     remove_select_user( &thread->obj );
     release_object( thread );
 }
@@ -639,9 +644,17 @@
 {
     struct thread *thread;
 
+    req->self = 0;
+    req->last = 0;
     if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE )))
     {
-        kill_thread( thread, req->exit_code );
+        thread->exit_code = req->exit_code;
+        if (thread != current) kill_thread( thread, 1 );
+        else
+        {
+            req->self = 1;
+            req->last = (thread->process->running_threads == 1);
+        }
         release_object( thread );
     }
 }
@@ -654,7 +667,7 @@
     if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
     {
         req->tid       = thread;
-        req->exit_code = thread->exit_code;
+        req->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STILL_ACTIVE;
         req->priority  = thread->priority;
         release_object( thread );
     }
diff --git a/server/thread.h b/server/thread.h
index 71baa51..54d38a4 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -74,7 +74,7 @@
 extern void resume_all_threads( void );
 extern int add_queue( struct object *obj, struct wait_queue_entry *entry );
 extern void remove_queue( struct object *obj, struct wait_queue_entry *entry );
-extern void kill_thread( struct thread *thread, int exit_code );
+extern void kill_thread( struct thread *thread, int violent_death );
 extern void wake_up( struct object *obj, int max );
 extern int sleep_on( int count, struct object *objects[], int flags,
                      int timeout, sleep_reply func );
@@ -85,7 +85,7 @@
 extern void wait4_thread( struct thread *thread, int signal );
 extern void stop_thread( struct thread *thread );
 extern void continue_thread( struct thread *thread );
-extern void detach_thread( struct thread *thread );
+extern void detach_thread( struct thread *thread, int sig );
 extern int suspend_for_ptrace( struct thread *thread );
 extern int read_thread_int( struct thread *thread, const int *addr, int *data );
 extern int write_thread_int( struct thread *thread, int *addr, int data, unsigned int mask );
diff --git a/server/trace.c b/server/trace.c
index d4ff840..cc1a1ba 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -297,12 +297,23 @@
     fprintf( stderr, " exit_code=%d", req->exit_code );
 }
 
+static void dump_terminate_process_reply( const struct terminate_process_request *req )
+{
+    fprintf( stderr, " self=%d", req->self );
+}
+
 static void dump_terminate_thread_request( const struct terminate_thread_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " exit_code=%d", req->exit_code );
 }
 
+static void dump_terminate_thread_reply( const struct terminate_thread_request *req )
+{
+    fprintf( stderr, " self=%d,", req->self );
+    fprintf( stderr, " last=%d", req->last );
+}
+
 static void dump_get_process_info_request( const struct get_process_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
@@ -1366,8 +1377,8 @@
     (dump_func)dump_init_process_done_reply,
     (dump_func)0,
     (dump_func)dump_get_thread_buffer_reply,
-    (dump_func)0,
-    (dump_func)0,
+    (dump_func)dump_terminate_process_reply,
+    (dump_func)dump_terminate_thread_reply,
     (dump_func)dump_get_process_info_reply,
     (dump_func)0,
     (dump_func)dump_get_thread_info_reply,