diff -Naur -X exclude-files ac_cur/arch/um/include/user_util.h ac/arch/um/include/user_util.h
--- ac_cur/arch/um/include/user_util.h	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/include/user_util.h	Tue Aug  7 10:39:52 2001
@@ -60,7 +60,8 @@
 extern __u64 file_size(char *file);
 extern void stop(void);
 extern int proc_start_thread(unsigned long ip, unsigned long sp);
-extern void stack_protections(unsigned long address, int len);
+extern void stack_protections(unsigned long address);
+extern void task_protections(unsigned long address);
 extern void abandon_proc_space(int (*proc)(void *), unsigned long sp);
 extern int signals(int (*init_proc)(void *), void *sp);
 extern void map(unsigned long virt, void *p, unsigned long len, 
diff -Naur -X exclude-files ac_cur/arch/um/kernel/exec_kern.c ac/arch/um/kernel/exec_kern.c
--- ac_cur/arch/um/kernel/exec_kern.c	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/kernel/exec_kern.c	Tue Aug  7 10:39:52 2001
@@ -45,11 +45,19 @@
 	if((vma == NULL) || (vma->vm_start > addr)) force_sigbus();
 }
 
+/* See comment above fork_tramp for why sigstop is defined and used like
+ * this
+ */
+
+static int sigstop = SIGSTOP;
+
 static int exec_tramp(void *sig_stack)
 {
+	int sig = sigstop;
+
 	block_signals();
 	init_new_thread(sig_stack, NULL);
-	kill(getpid(), SIGSTOP);
+	kill(getpid(), sig);
 	return(0);
 }
 
@@ -71,9 +79,7 @@
         current->thread.extern_pid = new_pid;
 	free_page(stack);
 	protect(physmem, high_physmem - physmem, 1, 1, 0);
-	stack = (unsigned long) current;
-	protect(stack + PAGE_SIZE, PAGE_SIZE, 0, 0, 0);
-	stack_protections(stack + 2 * PAGE_SIZE, 2 * PAGE_SIZE);
+	task_protections((unsigned long) current);
 	force_flush_all();
 	check_brk(brk_start);
 	unblock_signals();
diff -Naur -X exclude-files ac_cur/arch/um/kernel/ksyms.c ac/arch/um/kernel/ksyms.c
--- ac_cur/arch/um/kernel/ksyms.c	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/kernel/ksyms.c	Tue Aug  7 10:39:52 2001
@@ -4,6 +4,7 @@
 #include "asm/delay.h"
 #include "asm/processor.h"
 #include "asm/unistd.h"
+#include "asm/pgalloc.h"
 #include "kern_util.h"
 #include "user_util.h"
 
@@ -18,3 +19,5 @@
 EXPORT_SYMBOL(task_size);
 EXPORT_SYMBOL(__do_copy_from_user);
 EXPORT_SYMBOL(__do_strncpy_from_user);
+EXPORT_SYMBOL(flush_tlb_range);
+EXPORT_SYMBOL(__do_clear_user);
diff -Naur -X exclude-files ac_cur/arch/um/kernel/process.c ac/arch/um/kernel/process.c
--- ac_cur/arch/um/kernel/process.c	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/kernel/process.c	Tue Aug  7 10:39:52 2001
@@ -102,11 +102,25 @@
 	init_irq_signals(sig_stack != NULL);
 }
 
+/* This sigstop business works around a bug in gcc's -pg support.  
+ * Normally a procedure's mcount call comes after esp has been copied to 
+ * ebp and the new frame is constructed.  With procedures with no locals,
+ * the mcount comes before, as the first thing that the procedure does.
+ * When that procedure is main for a thread, ebp comes in as NULL.  So,
+ * when mcount dereferences it, it segfaults.  So, UML works around this
+ * by adding a non-optimizable local to the various trampolines, fork_tramp
+ * and outer_tramp below, and exec_tramp.
+ */
+
+static int sigstop = SIGSTOP;
+
 int fork_tramp(void *sig_stack)
 {
+	int sig = sigstop;
+
 	block_signals();
 	init_new_thread(sig_stack, finish_fork_handler);
-	kill(getpid(), SIGSTOP);
+	kill(getpid(), sig);
 	return(0);
 }
 
@@ -118,15 +132,20 @@
 	int pid;
 };
 
+/* See above for why sigkill is here */
+
+int sigkill = SIGKILL;
+
 int outer_tramp(void *arg)
 {
 	struct tramp *t;
+	int sig = sigkill;
 
 	t = arg;
 	t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
 		       t->flags, (void *) t->stack);
 	if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT);
-	kill(getpid(), SIGKILL);
+	kill(getpid(), sig);
 	exit(0);
 }
 
@@ -155,7 +174,7 @@
 	if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
 			  errno);
 	if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
-		panic("outer trampoline didn't exit 0");
+		panic("outer trampoline didn't exit with SIGKILL");
 
 	return(arg.pid);
 }
diff -Naur -X exclude-files ac_cur/arch/um/kernel/process_kern.c ac/arch/um/kernel/process_kern.c
--- ac_cur/arch/um/kernel/process_kern.c	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/kernel/process_kern.c	Tue Aug  7 10:39:52 2001
@@ -123,7 +123,7 @@
 
 	if((page = __get_free_page(GFP_KERNEL)) == 0)
 		panic("Couldn't allocate new stack");
-	stack_protections(page, PAGE_SIZE);
+	stack_protections(page);
 	return(page);
 }
 
@@ -515,15 +515,11 @@
 
 void finish_fork_handler(int sig)
 {
-	unsigned long stack;
-
 	init_flush_vm();
 	check_brk(brk_start);
 	if(current->mm != current->p_pptr->mm)
 		protect(physmem, high_physmem - physmem, 1, 1, 0);
-	stack = (unsigned long) current;
-	protect(stack + PAGE_SIZE, PAGE_SIZE, 0, 0, 0);
-	stack_protections(stack + 2 * PAGE_SIZE, 2 * PAGE_SIZE);
+	task_protections((unsigned long) current);
 	if(current->thread.request.u.fork_finish.from)
 		schedule_tail(current->thread.request.u.fork_finish.from);
 	free_page(current->thread.request.u.fork_finish.stack);
diff -Naur -X exclude-files ac_cur/arch/um/kernel/trap_user.c ac/arch/um/kernel/trap_user.c
--- ac_cur/arch/um/kernel/trap_user.c	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/kernel/trap_user.c	Tue Aug  7 10:39:52 2001
@@ -90,7 +90,7 @@
 
 extern void signal_usr1(int sig);
 
-int tracing_pid;
+int tracing_pid = -1;
 
 int signals(int (*init_proc)(void *), void *sp)
 {
diff -Naur -X exclude-files ac_cur/arch/um/kernel/um_arch.c ac/arch/um/kernel/um_arch.c
--- ac_cur/arch/um/kernel/um_arch.c	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/kernel/um_arch.c	Tue Aug  7 10:40:37 2001
@@ -295,8 +295,7 @@
 #ifndef CONFIG_SMP
 	current = &init_task;
 #endif 
-	protect(((unsigned long) &init_task) + PAGE_SIZE, PAGE_SIZE, 0, 0, 0);
-	stack_protections(init_task.thread.kernel_stack, 2 * PAGE_SIZE);
+ 	task_protections((unsigned long) &init_task);
 	sp = (void *) init_task.thread.kernel_stack + 2 * PAGE_SIZE - 
 		sizeof(unsigned long);
 	return(signals(start_kernel_proc, sp));
diff -Naur -X exclude-files ac_cur/arch/um/kernel/umid.c ac/arch/um/kernel/umid.c
--- ac_cur/arch/um/kernel/umid.c	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/kernel/umid.c	Tue Aug  7 10:39:52 2001
@@ -32,6 +32,8 @@
 	return(0);
 }
 
+extern int tracing_pid;
+
 static void create_pid_file(void)
 {
 	char file[sizeof("/tmp/uml/") + UMID_LEN + sizeof("/pid\0")];
@@ -46,7 +48,7 @@
 		return;
 	}
 
-	sprintf(pid, "%d\n", getpid());
+	sprintf(pid, "%d\n", (tracing_pid == -1) ?  getpid() : tracing_pid);
 	if(write(fd, pid, strlen(pid)) != strlen(pid))
 		printk("Write of pid file failed - errno = %d\n", errno);
 	close(fd);
diff -Naur -X exclude-files ac_cur/arch/um/kernel/user_util.c ac/arch/um/kernel/user_util.c
--- ac_cur/arch/um/kernel/user_util.c	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/kernel/user_util.c	Tue Aug  7 10:39:52 2001
@@ -172,9 +172,25 @@
 	while(1) sleep(1000000);
 }
 
-void stack_protections(unsigned long address, int len)
+void stack_protections(unsigned long address)
 {
-	mprotect((void *) address, len, PROT_READ | PROT_WRITE | PROT_EXEC);
+	int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+
+        if(mprotect((void *) address, page_size(), prot) < 0)
+		panic("protecting stack failed, errno = %d", errno);
+}
+
+void task_protections(unsigned long address)
+{
+	unsigned long guard = address + page_size();
+	unsigned long stack = guard + page_size();
+	int prot = 0;
+
+	if(mprotect((void *) stack, page_size(), prot) < 0)
+		panic("protecting guard page failed, errno = %d", errno);
+	prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+	if(mprotect((void *) stack, 2 * page_size(), prot) < 0)
+		panic("protecting stack failed, errno = %d", errno);
 }
 
 void protect(unsigned long addr, unsigned long len, int r, int w, int x)
@@ -183,10 +199,8 @@
 
 	prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
 		(x ? PROT_EXEC : 0);
-	if(mprotect((void *) addr, len, prot) == -1){
-		perror("Protecting a page");
-		panic("protect failed");
-	}
+	if(mprotect((void *) addr, len, prot) == -1)
+		panic("protect failed, errno = %d", errno);
 }
 
 int wait_for_stop(int pid, int sig, int cont_type)
diff -Naur -X exclude-files ac_cur/arch/um/ptproxy/sysdep.c ac/arch/um/ptproxy/sysdep.c
--- ac_cur/arch/um/ptproxy/sysdep.c	Tue Aug  7 09:49:45 2001
+++ ac/arch/um/ptproxy/sysdep.c	Tue Aug  7 10:39:52 2001
@@ -7,6 +7,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/ptrace.h>
 #include <asm/ptrace.h>