diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 8c2a4de..b1bf620 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -966,7 +966,7 @@ common/print-utils.h common/rsp-low.h nat/x86-dregs.h x86-linux-nat.h \
 i386-linux-nat.h common/common-defs.h common/errors.h common/common-types.h \
 common/common-debug.h common/cleanups.h common/gdb_setjmp.h \
 common/common-exceptions.h target/target.h common/symbol.h \
-common/common-regcache.h fbsd-tdep.h nat/linux-personality.h
+common/common-regcache.h fbsd-tdep.h nat/linux-personality.h nat/ptrace-utils.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -2295,6 +2295,10 @@ linux-personality.o: ${srcdir}/nat/linux-personality.c
 	$(COMPILE) $(srcdir)/nat/linux-personality.c
 	$(POSTCOMPILE)
 
+ptrace-utils.o: $(srcdir)/nat/ptrace-utils.c
+	$(COMPILE) $(srcdir)/nat/ptrace-utils.c
+	$(POSTCOMPILE)
+
 #
 # gdb/tui/ dependencies
 #
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index aae4853..523f5b8 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -24,6 +24,7 @@
 #include "gdbcore.h"
 #include "regcache.h"
 #include "linux-nat.h"
+#include "nat/ptrace-utils.h"
 #include "target-descriptions.h"
 #include "auxv.h"
 #include "gdbcmd.h"
@@ -469,7 +470,7 @@ fetch_gregs_from_thread (struct regcache *regcache)
 
   ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec);
   if (ret < 0)
-    perror_with_name (_("Unable to fetch general registers."));
+    throw_ptrace_error (_("Unable to fetch general registers."));
 
   for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
     regcache_raw_supply (regcache, regno,
@@ -493,7 +494,7 @@ store_gregs_to_thread (const struct regcache *regcache)
 
   ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec);
   if (ret < 0)
-    perror_with_name (_("Unable to fetch general registers."));
+    throw_ptrace_error (_("Unable to fetch general registers."));
 
   for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
     if (REG_VALID == regcache_register_status (regcache, regno))
@@ -502,7 +503,7 @@ store_gregs_to_thread (const struct regcache *regcache)
 
   ret = ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, &iovec);
   if (ret < 0)
-    perror_with_name (_("Unable to store general registers."));
+    throw_ptrace_error (_("Unable to store general registers."));
 }
 
 /* Fill GDB's register array with the fp/simd register values
@@ -522,7 +523,7 @@ fetch_fpregs_from_thread (struct regcache *regcache)
 
   ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec);
   if (ret < 0)
-    perror_with_name (_("Unable to fetch FP/SIMD registers."));
+    throw_ptrace_error (_("Unable to fetch FP/SIMD registers."));
 
   for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
     regcache_raw_supply (regcache, regno,
@@ -549,7 +550,7 @@ store_fpregs_to_thread (const struct regcache *regcache)
 
   ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec);
   if (ret < 0)
-    perror_with_name (_("Unable to fetch FP/SIMD registers."));
+    throw_ptrace_error (_("Unable to fetch FP/SIMD registers."));
 
   for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
     if (REG_VALID == regcache_register_status (regcache, regno))
@@ -563,7 +564,7 @@ store_fpregs_to_thread (const struct regcache *regcache)
 
   ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iovec);
   if (ret < 0)
-    perror_with_name (_("Unable to store FP/SIMD registers."));
+    throw_ptrace_error (_("Unable to store FP/SIMD registers."));
 }
 
 /* Implement the "to_fetch_register" target_ops method.  */
diff --git a/gdb/alphabsd-nat.c b/gdb/alphabsd-nat.c
index 37a5c8d..74757ab 100644
--- a/gdb/alphabsd-nat.c
+++ b/gdb/alphabsd-nat.c
@@ -24,6 +24,7 @@
 #include "alpha-tdep.h"
 #include "alphabsd-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 #include <sys/types.h>
 #include <sys/ptrace.h>
@@ -93,7 +94,7 @@ alphabsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       alphabsd_supply_reg (regcache, (char *) &gregs, regno);
       if (regno != -1)
@@ -107,7 +108,7 @@ alphabsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno);
     }
@@ -125,13 +126,13 @@ alphabsd_store_inferior_registers (struct target_ops *ops,
       struct reg gregs;
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
                   (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
-        perror_with_name (_("Couldn't get registers"));
+        throw_ptrace_error (_("Couldn't get registers"));
 
       alphabsd_fill_reg (regcache, (char *) &gregs, regno);
 
       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
                   (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
-        perror_with_name (_("Couldn't write registers"));
+        throw_ptrace_error (_("Couldn't write registers"));
 
       if (regno != -1)
 	return;
@@ -144,13 +145,13 @@ alphabsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno);
 
       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't write floating point status"));
+	throw_ptrace_error (_("Couldn't write floating point status"));
     }
 }
 
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 22a1359..e35a52e 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -31,6 +31,7 @@
 
 #include "amd64-nat.h"
 #include "linux-nat.h"
+#include "nat/ptrace-utils.h"
 #include "amd64-tdep.h"
 #include "amd64-linux-tdep.h"
 #include "i386-linux-tdep.h"
@@ -138,7 +139,7 @@ amd64_linux_fetch_inferior_registers (struct target_ops *ops,
       elf_gregset_t regs;
 
       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       amd64_supply_native_gregset (regcache, &regs, -1);
       if (regnum != -1)
@@ -158,14 +159,14 @@ amd64_linux_fetch_inferior_registers (struct target_ops *ops,
 	  iov.iov_len = sizeof (xstateregs);
 	  if (ptrace (PTRACE_GETREGSET, tid,
 		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
-	    perror_with_name (_("Couldn't get extended state status"));
+	    throw_ptrace_error (_("Couldn't get extended state status"));
 
 	  amd64_supply_xsave (regcache, -1, xstateregs);
 	}
       else
 	{
 	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
-	    perror_with_name (_("Couldn't get floating point status"));
+	    throw_ptrace_error (_("Couldn't get floating point status"));
 
 	  amd64_supply_fxsave (regcache, -1, &fpregs);
 	}
@@ -193,12 +194,12 @@ amd64_linux_store_inferior_registers (struct target_ops *ops,
       elf_gregset_t regs;
 
       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       amd64_collect_native_gregset (regcache, &regs, regnum);
 
       if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
-	perror_with_name (_("Couldn't write registers"));
+	throw_ptrace_error (_("Couldn't write registers"));
 
       if (regnum != -1)
 	return;
@@ -217,23 +218,23 @@ amd64_linux_store_inferior_registers (struct target_ops *ops,
 	  iov.iov_len = sizeof (xstateregs);
 	  if (ptrace (PTRACE_GETREGSET, tid,
 		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
-	    perror_with_name (_("Couldn't get extended state status"));
+	    throw_ptrace_error (_("Couldn't get extended state status"));
 
 	  amd64_collect_xsave (regcache, regnum, xstateregs, 0);
 
 	  if (ptrace (PTRACE_SETREGSET, tid,
 		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
-	    perror_with_name (_("Couldn't write extended state status"));
+	    throw_ptrace_error (_("Couldn't write extended state status"));
 	}
       else
 	{
 	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
-	    perror_with_name (_("Couldn't get floating point status"));
+	    throw_ptrace_error (_("Couldn't get floating point status"));
 
 	  amd64_collect_fxsave (regcache, regnum, &fpregs);
 
 	  if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
-	    perror_with_name (_("Couldn't write floating point status"));
+	    throw_ptrace_error (_("Couldn't write floating point status"));
 	}
     }
 }
diff --git a/gdb/amd64bsd-nat.c b/gdb/amd64bsd-nat.c
index 31060a123..e28715c 100644
--- a/gdb/amd64bsd-nat.c
+++ b/gdb/amd64bsd-nat.c
@@ -33,6 +33,7 @@
 #include "amd64-nat.h"
 #include "amd64bsd-nat.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
@@ -50,7 +51,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       amd64_supply_native_gregset (regcache, &regs, -1);
       if (regnum != -1)
@@ -63,7 +64,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       amd64_supply_fxsave (regcache, -1, &fpregs);
     }
@@ -84,13 +85,13 @@ amd64bsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't get registers"));
+        throw_ptrace_error (_("Couldn't get registers"));
 
       amd64_collect_native_gregset (regcache, &regs, regnum);
 
       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	          (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't write registers"));
+        throw_ptrace_error (_("Couldn't write registers"));
 
       if (regnum != -1)
 	return;
@@ -102,13 +103,13 @@ amd64bsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       amd64_collect_fxsave (regcache, regnum, &fpregs);
 
       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't write floating point status"));
+	throw_ptrace_error (_("Couldn't write floating point status"));
     }
 }
 
@@ -138,7 +139,7 @@ amd64bsd_dr_get (ptid_t ptid, int regnum)
 
   if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
-    perror_with_name (_("Couldn't read debug registers"));
+    throw_ptrace_error (_("Couldn't read debug registers"));
 
   return DBREG_DRX ((&dbregs), regnum);
 }
@@ -150,7 +151,7 @@ amd64bsd_dr_set (int regnum, unsigned long value)
 
   if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
-    perror_with_name (_("Couldn't get debug registers"));
+    throw_ptrace_error (_("Couldn't get debug registers"));
 
   /* For some mysterious reason, some of the reserved bits in the
      debug control register get set.  Mask these off, otherwise the
@@ -161,7 +162,7 @@ amd64bsd_dr_set (int regnum, unsigned long value)
 
   if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid),
               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
-    perror_with_name (_("Couldn't write debug registers"));
+    throw_ptrace_error (_("Couldn't write debug registers"));
 }
 
 void
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index bb8358c..34bc2db 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -22,6 +22,7 @@
 #include "regcache.h"
 #include "target.h"
 #include "linux-nat.h"
+#include "nat/ptrace-utils.h"
 #include "target-descriptions.h"
 #include "auxv.h"
 #include "observer.h"
@@ -1347,12 +1348,12 @@ arm_linux_prepare_to_resume (struct lwp_info *lwp)
         if (arm_hwbp_control_is_enabled (bpts[i].control))
           if (ptrace (PTRACE_SETHBPREGS, pid,
               (PTRACE_TYPE_ARG3) ((i << 1) + 1), &bpts[i].address) < 0)
-            perror_with_name (_("Unexpected error setting breakpoint"));
+            throw_ptrace_error (_("Unexpected error setting breakpoint"));
 
         if (bpts[i].control != 0)
           if (ptrace (PTRACE_SETHBPREGS, pid,
               (PTRACE_TYPE_ARG3) ((i << 1) + 2), &bpts[i].control) < 0)
-            perror_with_name (_("Unexpected error setting breakpoint"));
+            throw_ptrace_error (_("Unexpected error setting breakpoint"));
 
         arm_lwp_info->bpts_changed[i] = 0;
       }
@@ -1364,12 +1365,12 @@ arm_linux_prepare_to_resume (struct lwp_info *lwp)
         if (arm_hwbp_control_is_enabled (wpts[i].control))
           if (ptrace (PTRACE_SETHBPREGS, pid,
               (PTRACE_TYPE_ARG3) -((i << 1) + 1), &wpts[i].address) < 0)
-            perror_with_name (_("Unexpected error setting watchpoint"));
+            throw_ptrace_error (_("Unexpected error setting watchpoint"));
 
         if (wpts[i].control != 0)
           if (ptrace (PTRACE_SETHBPREGS, pid,
               (PTRACE_TYPE_ARG3) -((i << 1) + 2), &wpts[i].control) < 0)
-            perror_with_name (_("Unexpected error setting watchpoint"));
+            throw_ptrace_error (_("Unexpected error setting watchpoint"));
 
         arm_lwp_info->wpts_changed[i] = 0;
       }
diff --git a/gdb/config/aarch64/linux.mh b/gdb/config/aarch64/linux.mh
index 7f96e4d..3b47df2 100644
--- a/gdb/config/aarch64/linux.mh
+++ b/gdb/config/aarch64/linux.mh
@@ -19,7 +19,7 @@
 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o aarch64-linux-nat.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o aarch64-linux-nat.o \
 	proc-service.o linux-thread-db.o linux-nat.o linux-fork.o \
 	linux-procfs.o linux-ptrace.o linux-osdata.o linux-waitpid.o \
 	linux-personality.o
diff --git a/gdb/config/alpha/alpha-linux.mh b/gdb/config/alpha/alpha-linux.mh
index 2ea02a1..b2ac9b5 100644
--- a/gdb/config/alpha/alpha-linux.mh
+++ b/gdb/config/alpha/alpha-linux.mh
@@ -1,6 +1,6 @@
 # Host: Little-endian Alpha running Linux
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o alpha-linux-nat.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o alpha-linux-nat.o \
 	fork-child.o proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
 	linux-waitpid.o linux-personality.o
diff --git a/gdb/config/alpha/fbsd.mh b/gdb/config/alpha/fbsd.mh
index 6d1fe29..3867ca6 100644
--- a/gdb/config/alpha/fbsd.mh
+++ b/gdb/config/alpha/fbsd.mh
@@ -1,5 +1,5 @@
 # Host: FreeBSD/alpha
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	fbsd-nat.o alphabsd-nat.o bsd-kvm.o \
 	core-regset.o
 
diff --git a/gdb/config/alpha/nbsd.mh b/gdb/config/alpha/nbsd.mh
index b4185a7..b4b160f 100644
--- a/gdb/config/alpha/nbsd.mh
+++ b/gdb/config/alpha/nbsd.mh
@@ -1,4 +1,4 @@
 # Host: NetBSD/alpha
-NATDEPFILES= fork-child.o inf-ptrace.o alphabsd-nat.o bsd-kvm.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o alphabsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/arm/linux.mh b/gdb/config/arm/linux.mh
index 549bf42..9304e5d 100644
--- a/gdb/config/arm/linux.mh
+++ b/gdb/config/arm/linux.mh
@@ -1,7 +1,7 @@
 # Host: ARM based machine running GNU/Linux
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o arm-linux-nat.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o arm-linux-nat.o \
 	proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
 	linux-waitpid.o linux-personality.o
diff --git a/gdb/config/arm/nbsdelf.mh b/gdb/config/arm/nbsdelf.mh
index 4efb8a3..c1f122a 100644
--- a/gdb/config/arm/nbsdelf.mh
+++ b/gdb/config/arm/nbsdelf.mh
@@ -1,2 +1,2 @@
 # Host: NetBSD/arm
-NATDEPFILES= fork-child.o inf-ptrace.o armnbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o armnbsd-nat.o
diff --git a/gdb/config/i386/fbsd.mh b/gdb/config/i386/fbsd.mh
index e5bff3a..37e19cb 100644
--- a/gdb/config/i386/fbsd.mh
+++ b/gdb/config/i386/fbsd.mh
@@ -1,5 +1,5 @@
 # Host: FreeBSD/i386
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	fbsd-nat.o x86-nat.o x86-dregs.o i386bsd-nat.o i386fbsd-nat.o \
 	bsd-kvm.o
 NAT_FILE= nm-fbsd.h
diff --git a/gdb/config/i386/fbsd64.mh b/gdb/config/i386/fbsd64.mh
index 329c526..3b82c7f 100644
--- a/gdb/config/i386/fbsd64.mh
+++ b/gdb/config/i386/fbsd64.mh
@@ -1,5 +1,5 @@
 # Host: FreeBSD/amd64
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	fbsd-nat.o amd64-nat.o amd64bsd-nat.o amd64fbsd-nat.o \
 	bsd-kvm.o x86-nat.o x86-dregs.o
 HAVE_NATIVE_GCORE_HOST = 1
diff --git a/gdb/config/i386/linux.mh b/gdb/config/i386/linux.mh
index 33fb281..c941245 100644
--- a/gdb/config/i386/linux.mh
+++ b/gdb/config/i386/linux.mh
@@ -1,7 +1,7 @@
 # Host: Intel 386 running GNU/Linux.
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o \
 	x86-nat.o x86-dregs.o i386-linux-nat.o x86-linux-nat.o \
 	proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
diff --git a/gdb/config/i386/linux64.mh b/gdb/config/i386/linux64.mh
index d52eb52..d5b45d0 100644
--- a/gdb/config/i386/linux64.mh
+++ b/gdb/config/i386/linux64.mh
@@ -1,5 +1,5 @@
 # Host: GNU/Linux x86-64
-NATDEPFILES= inf-ptrace.o fork-child.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o \
 	x86-nat.o x86-dregs.o amd64-nat.o amd64-linux-nat.o \
 	x86-linux-nat.o \
 	linux-nat.o linux-osdata.o \
diff --git a/gdb/config/i386/nbsd64.mh b/gdb/config/i386/nbsd64.mh
index 5de8cf5..369a32d 100644
--- a/gdb/config/i386/nbsd64.mh
+++ b/gdb/config/i386/nbsd64.mh
@@ -1,3 +1,3 @@
 # Host: NetBSD/amd64
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	nbsd-nat.o amd64-nat.o amd64bsd-nat.o amd64nbsd-nat.o
diff --git a/gdb/config/i386/nbsdelf.mh b/gdb/config/i386/nbsdelf.mh
index d27c842..087696d 100644
--- a/gdb/config/i386/nbsdelf.mh
+++ b/gdb/config/i386/nbsdelf.mh
@@ -1,5 +1,5 @@
 # Host: NetBSD/i386 ELF
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	nbsd-nat.o i386bsd-nat.o i386nbsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/i386/obsd.mh b/gdb/config/i386/obsd.mh
index a9041f4..15383f1 100644
--- a/gdb/config/i386/obsd.mh
+++ b/gdb/config/i386/obsd.mh
@@ -1,5 +1,5 @@
 # Host: OpenBSD/i386 ELF
-NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o obsd-nat.o \
 	i386bsd-nat.o i386obsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/i386/obsd64.mh b/gdb/config/i386/obsd64.mh
index 386a582..abd06b9 100644
--- a/gdb/config/i386/obsd64.mh
+++ b/gdb/config/i386/obsd64.mh
@@ -1,5 +1,5 @@
 # Host: OpenBSD/amd64
-NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o obsd-nat.o \
 	amd64-nat.o amd64bsd-nat.o amd64obsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/ia64/linux.mh b/gdb/config/ia64/linux.mh
index 9dce22b..c502340 100644
--- a/gdb/config/ia64/linux.mh
+++ b/gdb/config/ia64/linux.mh
@@ -1,7 +1,7 @@
 # Host: Intel IA-64 running GNU/Linux
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o \
 	ia64-linux-nat.o \
 	proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o \
diff --git a/gdb/config/m32r/linux.mh b/gdb/config/m32r/linux.mh
index 6b810e6..6a9456f 100644
--- a/gdb/config/m32r/linux.mh
+++ b/gdb/config/m32r/linux.mh
@@ -1,7 +1,7 @@
 # Host: M32R based machine running GNU/Linux
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o				\
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o				\
 	m32r-linux-nat.o proc-service.o linux-thread-db.o	\
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
 	linux-waitpid.o linux-personality.o
diff --git a/gdb/config/m68k/linux.mh b/gdb/config/m68k/linux.mh
index f3b3baa..8317666 100644
--- a/gdb/config/m68k/linux.mh
+++ b/gdb/config/m68k/linux.mh
@@ -1,7 +1,7 @@
 # Host: Motorola m68k running GNU/Linux.
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o \
 	m68klinux-nat.o \
 	proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
diff --git a/gdb/config/m68k/nbsdelf.mh b/gdb/config/m68k/nbsdelf.mh
index f2d97a1..7d458a7 100644
--- a/gdb/config/m68k/nbsdelf.mh
+++ b/gdb/config/m68k/nbsdelf.mh
@@ -1,4 +1,4 @@
 # Host: NetBSD/m68k ELF
-NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o inf-ptrace.o
+NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o inf-ptrace.o ptrace-utils.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/m68k/obsd.mh b/gdb/config/m68k/obsd.mh
index 7930e3b..92c00d7 100644
--- a/gdb/config/m68k/obsd.mh
+++ b/gdb/config/m68k/obsd.mh
@@ -1,4 +1,4 @@
 # Host: OpenBSD/m68k
-NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o inf-ptrace.o
+NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o inf-ptrace.o ptrace-utils.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/m88k/obsd.mh b/gdb/config/m88k/obsd.mh
index 2978edf..a9c9365 100644
--- a/gdb/config/m88k/obsd.mh
+++ b/gdb/config/m88k/obsd.mh
@@ -1,2 +1,2 @@
 # Host: OpenBSD/m88k
-NATDEPFILES= fork-child.o inf-ptrace.o m88kbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o m88kbsd-nat.o
diff --git a/gdb/config/mips/linux.mh b/gdb/config/mips/linux.mh
index d6a802f..eabc470 100644
--- a/gdb/config/mips/linux.mh
+++ b/gdb/config/mips/linux.mh
@@ -1,6 +1,6 @@
 # Host: Linux/MIPS
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o mips-linux-nat.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o mips-linux-nat.o \
 	linux-thread-db.o proc-service.o \
 	linux-nat.o linux-osdata.o linux-fork.o \
 	linux-procfs.o linux-ptrace.o linux-waitpid.o \
diff --git a/gdb/config/mips/nbsd.mh b/gdb/config/mips/nbsd.mh
index b76df13..fe437dd 100644
--- a/gdb/config/mips/nbsd.mh
+++ b/gdb/config/mips/nbsd.mh
@@ -1,2 +1,2 @@
 # Host: NetBSD/mips
-NATDEPFILES= fork-child.o inf-ptrace.o mipsnbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o mipsnbsd-nat.o
diff --git a/gdb/config/mips/obsd64.mh b/gdb/config/mips/obsd64.mh
index ed04f9e..e9b7a7f 100644
--- a/gdb/config/mips/obsd64.mh
+++ b/gdb/config/mips/obsd64.mh
@@ -1,2 +1,2 @@
 # Host: OpenBSD/mips64
-NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o mips64obsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o obsd-nat.o mips64obsd-nat.o
diff --git a/gdb/config/pa/hpux.mh b/gdb/config/pa/hpux.mh
index 3151120..ec61058 100644
--- a/gdb/config/pa/hpux.mh
+++ b/gdb/config/pa/hpux.mh
@@ -1,3 +1,3 @@
 # Host: PA-RISC HP-UX
-NATDEPFILES= fork-child.o inf-ptrace.o inf-ttrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o inf-ttrace.o \
 	hppa-hpux-nat.o
diff --git a/gdb/config/pa/linux.mh b/gdb/config/pa/linux.mh
index 9539b64..15c3752 100644
--- a/gdb/config/pa/linux.mh
+++ b/gdb/config/pa/linux.mh
@@ -1,6 +1,6 @@
 # Host: Hewlett-Packard PA-RISC machine, running Linux
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o \
 	hppa-linux-nat.o proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o \
 	linux-procfs.o linux-ptrace.o linux-waitpid.o \
diff --git a/gdb/config/pa/nbsd.mh b/gdb/config/pa/nbsd.mh
index 5cff698..ff34c78 100644
--- a/gdb/config/pa/nbsd.mh
+++ b/gdb/config/pa/nbsd.mh
@@ -1,2 +1,2 @@
 # Host: NetBSD/hppa
-NATDEPFILES= fork-child.o inf-ptrace.o nbsd-nat.o hppanbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o nbsd-nat.o hppanbsd-nat.o
diff --git a/gdb/config/pa/obsd.mh b/gdb/config/pa/obsd.mh
index 50a1192..8e025b8 100644
--- a/gdb/config/pa/obsd.mh
+++ b/gdb/config/pa/obsd.mh
@@ -1,2 +1,2 @@
 # Host: OpenBSD/hppa
-NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o hppaobsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o obsd-nat.o hppaobsd-nat.o
diff --git a/gdb/config/powerpc/aix.mh b/gdb/config/powerpc/aix.mh
index 141501d..52930df 100644
--- a/gdb/config/powerpc/aix.mh
+++ b/gdb/config/powerpc/aix.mh
@@ -1,7 +1,7 @@
 # Host: IBM PowerPC running AIX
 
 # aix-thread.o is not listed in NATDEPFILES as it is pulled in by configure.
-NATDEPFILES= fork-child.o inf-ptrace.o rs6000-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o rs6000-nat.o
 
 # When compiled with cc, for debugging, this argument should be passed.
 # We have no idea who our current compiler is though, so we skip it.
diff --git a/gdb/config/powerpc/fbsd.mh b/gdb/config/powerpc/fbsd.mh
index e4e7b47..1ed4f49 100644
--- a/gdb/config/powerpc/fbsd.mh
+++ b/gdb/config/powerpc/fbsd.mh
@@ -17,7 +17,7 @@
 #  You should have received a copy of the GNU General Public License
 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-NATDEPFILES= fbsd-nat.o fork-child.o inf-ptrace.o ppcfbsd-nat.o bsd-kvm.o
+NATDEPFILES= fbsd-nat.o fork-child.o inf-ptrace.o ptrace-utils.o ppcfbsd-nat.o bsd-kvm.o
 HAVE_NATIVE_GCORE_HOST = 1
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/powerpc/linux.mh b/gdb/config/powerpc/linux.mh
index 76e62c0..44f4a91 100644
--- a/gdb/config/powerpc/linux.mh
+++ b/gdb/config/powerpc/linux.mh
@@ -3,7 +3,7 @@
 XM_CLIBS=
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o \
 	ppc-linux-nat.o proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
 	linux-waitpid.o linux-personality.o
diff --git a/gdb/config/powerpc/nbsd.mh b/gdb/config/powerpc/nbsd.mh
index db0390c..edea9dd 100644
--- a/gdb/config/powerpc/nbsd.mh
+++ b/gdb/config/powerpc/nbsd.mh
@@ -1,4 +1,4 @@
 # Host: NetBSD/powerpc
-NATDEPFILES= fork-child.o inf-ptrace.o ppcnbsd-nat.o bsd-kvm.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o ppcnbsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/powerpc/obsd.mh b/gdb/config/powerpc/obsd.mh
index 2af667a..f8892ba 100644
--- a/gdb/config/powerpc/obsd.mh
+++ b/gdb/config/powerpc/obsd.mh
@@ -1,4 +1,4 @@
 # Host: OpenBSD/powerpc
-NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o ppcobsd-nat.o bsd-kvm.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o obsd-nat.o ppcobsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/powerpc/ppc64-linux.mh b/gdb/config/powerpc/ppc64-linux.mh
index 7eb6507..80c80fd 100644
--- a/gdb/config/powerpc/ppc64-linux.mh
+++ b/gdb/config/powerpc/ppc64-linux.mh
@@ -3,7 +3,7 @@
 XM_CLIBS=
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o \
 	ppc-linux-nat.o proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
 	linux-waitpid.o ppc-linux.o linux-personality.o
diff --git a/gdb/config/powerpc/spu-linux.mh b/gdb/config/powerpc/spu-linux.mh
index d44aeeb..38f1588 100644
--- a/gdb/config/powerpc/spu-linux.mh
+++ b/gdb/config/powerpc/spu-linux.mh
@@ -3,6 +3,6 @@
 # This implements a 'pseudo-native' GDB running on the
 # PPU side of the Cell BE and debugging the SPU side.
 
-NATDEPFILES = spu-linux-nat.o fork-child.o inf-ptrace.o \
+NATDEPFILES = spu-linux-nat.o fork-child.o inf-ptrace.o ptrace-utils.o \
 	      linux-procfs.o linux-ptrace.o linux-waitpid.o linux-personality.o
 
diff --git a/gdb/config/s390/linux.mh b/gdb/config/s390/linux.mh
index e1ad899..11fd721 100644
--- a/gdb/config/s390/linux.mh
+++ b/gdb/config/s390/linux.mh
@@ -1,6 +1,6 @@
 # Host: S390, running Linux
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o s390-linux-nat.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o s390-linux-nat.o \
 	linux-thread-db.o proc-service.o \
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
 	linux-personality.o \
diff --git a/gdb/config/sh/nbsd.mh b/gdb/config/sh/nbsd.mh
index d5e67cb..d97e699 100644
--- a/gdb/config/sh/nbsd.mh
+++ b/gdb/config/sh/nbsd.mh
@@ -1,2 +1,2 @@
 # Host: NetBSD/sh
-NATDEPFILES= fork-child.o inf-ptrace.o shnbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o shnbsd-nat.o
diff --git a/gdb/config/sparc/fbsd.mh b/gdb/config/sparc/fbsd.mh
index 2774efb..45579b4 100644
--- a/gdb/config/sparc/fbsd.mh
+++ b/gdb/config/sparc/fbsd.mh
@@ -1,5 +1,5 @@
 # Host: FreeBSD/sparc64
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	fbsd-nat.o sparc-nat.o sparc64-nat.o sparc64fbsd-nat.o \
 	bsd-kvm.o
 HAVE_NATIVE_GCORE_HOST = 1
diff --git a/gdb/config/sparc/linux.mh b/gdb/config/sparc/linux.mh
index bd7fc86..3b43eab 100644
--- a/gdb/config/sparc/linux.mh
+++ b/gdb/config/sparc/linux.mh
@@ -1,7 +1,7 @@
 # Host: GNU/Linux SPARC
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= sparc-nat.o sparc-linux-nat.o \
-	fork-child.o inf-ptrace.o \
+	fork-child.o inf-ptrace.o ptrace-utils.o \
 	proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o \
 	linux-procfs.o linux-ptrace.o linux-waitpid.o \
diff --git a/gdb/config/sparc/linux64.mh b/gdb/config/sparc/linux64.mh
index 86f984f..2f4d163 100644
--- a/gdb/config/sparc/linux64.mh
+++ b/gdb/config/sparc/linux64.mh
@@ -1,7 +1,7 @@
 # Host: GNU/Linux UltraSPARC
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= sparc-nat.o sparc64-nat.o sparc64-linux-nat.o \
-	fork-child.o inf-ptrace.o \
+	fork-child.o inf-ptrace.o ptrace-utils.o \
 	proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o \
 	linux-procfs.o linux-ptrace.o linux-waitpid.o \
diff --git a/gdb/config/sparc/nbsd64.mh b/gdb/config/sparc/nbsd64.mh
index 056b74d..5a9ea07 100644
--- a/gdb/config/sparc/nbsd64.mh
+++ b/gdb/config/sparc/nbsd64.mh
@@ -1,5 +1,5 @@
 # Host: NetBSD/sparc64
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	sparc64nbsd-nat.o sparc-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/sparc/nbsdelf.mh b/gdb/config/sparc/nbsdelf.mh
index 6bf898f..6ae92bf 100644
--- a/gdb/config/sparc/nbsdelf.mh
+++ b/gdb/config/sparc/nbsdelf.mh
@@ -1,5 +1,5 @@
 # Host: NetBSD/sparc ELF
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	sparc-nat.o sparcnbsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/sparc/obsd64.mh b/gdb/config/sparc/obsd64.mh
index d15e34d..d82386c 100644
--- a/gdb/config/sparc/obsd64.mh
+++ b/gdb/config/sparc/obsd64.mh
@@ -1,5 +1,5 @@
 # Host: OpenBSD/sparc64
-NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o obsd-nat.o \
 	sparc64obsd-nat.o sparc-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/tilegx/linux.mh b/gdb/config/tilegx/linux.mh
index b5edcd4..cdc96b9 100644
--- a/gdb/config/tilegx/linux.mh
+++ b/gdb/config/tilegx/linux.mh
@@ -1,7 +1,7 @@
 # Host: Tilera TILE-Gx running GNU/Linux.
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o \
 	tilegx-linux-nat.o \
 	proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o \
diff --git a/gdb/config/vax/nbsdelf.mh b/gdb/config/vax/nbsdelf.mh
index dd9441b..28f0276 100644
--- a/gdb/config/vax/nbsdelf.mh
+++ b/gdb/config/vax/nbsdelf.mh
@@ -1,5 +1,5 @@
 # Host: NetBSD/vax ELF
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	vaxbsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/vax/obsd.mh b/gdb/config/vax/obsd.mh
index d4d444f..57e729e 100644
--- a/gdb/config/vax/obsd.mh
+++ b/gdb/config/vax/obsd.mh
@@ -1,5 +1,5 @@
 # Host: OpenBSD/vax
-NATDEPFILES= fork-child.o inf-ptrace.o \
+NATDEPFILES= fork-child.o inf-ptrace.o ptrace-utils.o \
 	vaxbsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/xtensa/linux.mh b/gdb/config/xtensa/linux.mh
index b4e59b3..50779d8 100644
--- a/gdb/config/xtensa/linux.mh
+++ b/gdb/config/xtensa/linux.mh
@@ -2,7 +2,7 @@
 
 NAT_FILE= config/nm-linux.h
 
-NATDEPFILES= inf-ptrace.o fork-child.o xtensa-linux-nat.o \
+NATDEPFILES= inf-ptrace.o ptrace-utils.o fork-child.o xtensa-linux-nat.o \
 	linux-thread-db.o proc-service.o \
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
 	linux-waitpid.o linux-personality.o
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 6dddf26..f3ef383 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -179,7 +179,8 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(srcdir)/common/rsp-low.c $(srcdir)/common/errors.c \
 	$(srcdir)/common/common-debug.c $(srcdir)/common/cleanups.c \
 	$(srcdir)/common/common-exceptions.c $(srcdir)/symbol.c \
-	$(srcdir)/common/btrace-common.c
+	$(srcdir)/common/btrace-common.c \
+	$(srcdir)/nat/ptrace-utils.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -605,6 +606,9 @@ linux-personality.o: ../nat/linux-personality.c
 btrace-common.o: ../common/btrace-common.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+ptrace-utils.o: ../nat/ptrace-utils.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
 
 aarch64.c : $(srcdir)/../regformats/aarch64.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/aarch64.dat aarch64.c
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 98dd0d9..69fe157 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -42,7 +42,7 @@ srv_amd64_linux_xmlfiles="i386/amd64-linux.xml i386/amd64-avx-linux.xml i386/amd
 
 # Linux object files.  This is so we don't have to repeat
 # these files over and over again.
-srv_linux_obj="linux-low.o linux-osdata.o linux-procfs.o linux-ptrace.o linux-waitpid.o linux-personality.o"
+srv_linux_obj="linux-low.o linux-osdata.o linux-procfs.o linux-ptrace.o linux-waitpid.o linux-personality.o ptrace-utils.o"
 
 # Input is taken from the "${target}" variable.
 
diff --git a/gdb/hppanbsd-nat.c b/gdb/hppanbsd-nat.c
index 0c96b49..568de05 100644
--- a/gdb/hppanbsd-nat.c
+++ b/gdb/hppanbsd-nat.c
@@ -27,6 +27,7 @@
 
 #include "hppa-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 #include "nbsd-nat.h"
 
@@ -169,7 +170,7 @@ hppanbsd_fetch_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       hppanbsd_supply_gregset (regcache, &regs);
     }
@@ -180,7 +181,7 @@ hppanbsd_fetch_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       hppanbsd_supply_fpregset (regcache, &fpregs);
     }
@@ -199,13 +200,13 @@ hppanbsd_store_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't get registers"));
+        throw_ptrace_error (_("Couldn't get registers"));
 
       hppanbsd_collect_gregset (regcache, &regs, regnum);
 
       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	          (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't write registers"));
+        throw_ptrace_error (_("Couldn't write registers"));
     }
 
   if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
@@ -214,13 +215,13 @@ hppanbsd_store_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
 
       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't write floating point status"));
+	throw_ptrace_error (_("Couldn't write floating point status"));
     }
 }
 
diff --git a/gdb/hppaobsd-nat.c b/gdb/hppaobsd-nat.c
index fe49b99..5728b6c 100644
--- a/gdb/hppaobsd-nat.c
+++ b/gdb/hppaobsd-nat.c
@@ -28,6 +28,7 @@
 
 #include "hppa-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 #include "obsd-nat.h"
 
@@ -195,7 +196,7 @@ hppaobsd_fetch_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       hppaobsd_supply_gregset (regcache, &regs);
     }
@@ -206,7 +207,7 @@ hppaobsd_fetch_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       hppaobsd_supply_fpregset (regcache, &fpregs);
     }
@@ -225,13 +226,13 @@ hppaobsd_store_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't get registers"));
+        throw_ptrace_error (_("Couldn't get registers"));
 
       hppaobsd_collect_gregset (regcache, &regs, regnum);
 
       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	          (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't write registers"));
+        throw_ptrace_error (_("Couldn't write registers"));
     }
 
   if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum))
@@ -240,13 +241,13 @@ hppaobsd_store_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       hppaobsd_collect_fpregset (regcache, &fpregs, regnum);
 
       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't write floating point status"));
+	throw_ptrace_error (_("Couldn't write floating point status"));
     }
 }
 
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index 8cb8c66..1a0dfc0 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -34,6 +34,7 @@
 #include "x86-xstate.h"
 
 #include "x86-linux-nat.h"
+#include "nat/ptrace-utils.h"
 
 /* The register sets used in GNU/Linux ELF core-dumps are identical to
    the register sets in `struct user' that is used for a.out
@@ -212,7 +213,7 @@ fetch_regs (struct regcache *regcache, int tid)
 	  return;
 	}
 
-      perror_with_name (_("Couldn't get registers"));
+      throw_ptrace_error (_("Couldn't get registers"));
     }
 
   supply_gregset (regcache, (const elf_gregset_t *) regs_p);
@@ -227,12 +228,12 @@ store_regs (const struct regcache *regcache, int tid, int regno)
   elf_gregset_t regs;
 
   if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   fill_gregset (regcache, &regs, regno);
   
   if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 }
 
 #else
@@ -276,7 +277,7 @@ fetch_fpregs (struct regcache *regcache, int tid)
   elf_fpregset_t fpregs;
 
   if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
-    perror_with_name (_("Couldn't get floating point status"));
+    throw_ptrace_error (_("Couldn't get floating point status"));
 
   supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
 }
@@ -290,12 +291,12 @@ store_fpregs (const struct regcache *regcache, int tid, int regno)
   elf_fpregset_t fpregs;
 
   if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
-    perror_with_name (_("Couldn't get floating point status"));
+    throw_ptrace_error (_("Couldn't get floating point status"));
 
   fill_fpregset (regcache, &fpregs, regno);
 
   if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
-    perror_with_name (_("Couldn't write floating point status"));
+    throw_ptrace_error (_("Couldn't write floating point status"));
 }
 
 #else
@@ -332,7 +333,7 @@ fetch_xstateregs (struct regcache *regcache, int tid)
   iov.iov_len = sizeof(xstateregs);
   if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE,
 	      &iov) < 0)
-    perror_with_name (_("Couldn't read extended state status"));
+    throw_ptrace_error (_("Couldn't read extended state status"));
 
   i387_supply_xsave (regcache, -1, xstateregs);
   return 1;
@@ -355,13 +356,13 @@ store_xstateregs (const struct regcache *regcache, int tid, int regno)
   iov.iov_len = sizeof(xstateregs);
   if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE,
 	      &iov) < 0)
-    perror_with_name (_("Couldn't read extended state status"));
+    throw_ptrace_error (_("Couldn't read extended state status"));
 
   i387_collect_xsave (regcache, regno, xstateregs, 0);
 
   if (ptrace (PTRACE_SETREGSET, tid, (unsigned int) NT_X86_XSTATE,
 	      (int) &iov) < 0)
-    perror_with_name (_("Couldn't write extended state status"));
+    throw_ptrace_error (_("Couldn't write extended state status"));
 
   return 1;
 }
@@ -388,7 +389,7 @@ fetch_fpxregs (struct regcache *regcache, int tid)
 	  return 0;
 	}
 
-      perror_with_name (_("Couldn't read floating-point and SSE registers"));
+      throw_ptrace_error (_("Couldn't read floating-point and SSE registers"));
     }
 
   i387_supply_fxsave (regcache, -1, (const elf_fpxregset_t *) &fpxregs);
@@ -415,13 +416,13 @@ store_fpxregs (const struct regcache *regcache, int tid, int regno)
 	  return 0;
 	}
 
-      perror_with_name (_("Couldn't read floating-point and SSE registers"));
+      throw_ptrace_error (_("Couldn't read floating-point and SSE registers"));
     }
 
   i387_collect_fxsave (regcache, regno, &fpxregs);
 
   if (ptrace (PTRACE_SETFPXREGS, tid, 0, &fpxregs) == -1)
-    perror_with_name (_("Couldn't write floating-point and SSE registers"));
+    throw_ptrace_error (_("Couldn't write floating-point and SSE registers"));
 
   return 1;
 }
@@ -709,7 +710,7 @@ i386_linux_resume (struct target_ops *ops,
     }
 
   if (ptrace (request, pid, 0, gdb_signal_to_host (signal)) == -1)
-    perror_with_name (("ptrace"));
+    throw_ptrace_error (("ptrace"));
 }
 
 
diff --git a/gdb/i386bsd-nat.c b/gdb/i386bsd-nat.c
index 16e0707..44b24b0 100644
--- a/gdb/i386bsd-nat.c
+++ b/gdb/i386bsd-nat.c
@@ -31,6 +31,7 @@
 #include "i387-tdep.h"
 #include "i386bsd-nat.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 
 /* In older BSD versions we cannot get at some of the segment
@@ -136,7 +137,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       i386bsd_supply_gregset (regcache, &regs);
       if (regnum != -1)
@@ -160,14 +161,14 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops,
 	{
           if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	    perror_with_name (_("Couldn't get floating point status"));
+	    throw_ptrace_error (_("Couldn't get floating point status"));
 
 	  i387_supply_fsave (regcache, -1, &fpregs);
 	}
 #else
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       i387_supply_fsave (regcache, -1, &fpregs);
 #endif
@@ -187,13 +188,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't get registers"));
+        throw_ptrace_error (_("Couldn't get registers"));
 
       i386bsd_collect_gregset (regcache, &regs, regnum);
 
       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	          (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't write registers"));
+        throw_ptrace_error (_("Couldn't write registers"));
 
       if (regnum != -1)
 	return;
@@ -215,7 +216,7 @@ i386bsd_store_inferior_registers (struct target_ops *ops,
 
 	  if (ptrace (PT_SETXMMREGS, ptid_get_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) xmmregs, 0) == -1)
-            perror_with_name (_("Couldn't write XMM registers"));
+            throw_ptrace_error (_("Couldn't write XMM registers"));
 	}
       else
 	{
@@ -223,13 +224,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops,
 #endif
           if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	    perror_with_name (_("Couldn't get floating point status"));
+	    throw_ptrace_error (_("Couldn't get floating point status"));
 
           i387_collect_fsave (regcache, regnum, &fpregs);
 
           if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	    perror_with_name (_("Couldn't write floating point status"));
+	    throw_ptrace_error (_("Couldn't write floating point status"));
 #ifdef HAVE_PT_GETXMMREGS
         }
 #endif
@@ -268,7 +269,7 @@ i386bsd_dr_get (ptid_t ptid, int regnum)
 
   if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
-    perror_with_name (_("Couldn't read debug registers"));
+    throw_ptrace_error (_("Couldn't read debug registers"));
 
   return DBREG_DRX ((&dbregs), regnum);
 }
@@ -280,7 +281,7 @@ i386bsd_dr_set (int regnum, unsigned int value)
 
   if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
-    perror_with_name (_("Couldn't get debug registers"));
+    throw_ptrace_error (_("Couldn't get debug registers"));
 
   /* For some mysterious reason, some of the reserved bits in the
      debug control register get set.  Mask these off, otherwise the
@@ -291,7 +292,7 @@ i386bsd_dr_set (int regnum, unsigned int value)
 
   if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid),
               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
-    perror_with_name (_("Couldn't write debug registers"));
+    throw_ptrace_error (_("Couldn't write debug registers"));
 }
 
 void
diff --git a/gdb/i386fbsd-nat.c b/gdb/i386fbsd-nat.c
index ad439e3..ad37c13 100644
--- a/gdb/i386fbsd-nat.c
+++ b/gdb/i386fbsd-nat.c
@@ -31,6 +31,7 @@
 #include "i386-tdep.h"
 #include "x86-nat.h"
 #include "i386bsd-nat.h"
+#include "nat/ptrace-utils.h"
 
 /* Resume execution of the inferior process.  If STEP is nonzero,
    single-step it.  If SIGNAL is nonzero, give it that signal.  */
@@ -77,7 +78,7 @@ i386fbsd_resume (struct target_ops *ops,
      written a new PC value to the child.)  */
   if (ptrace (request, pid, (caddr_t) 1,
 	      gdb_signal_to_host (signal)) == -1)
-    perror_with_name (("ptrace"));
+    throw_ptrace_error (("ptrace"));
 }
 
 
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index cd58dfb..06382d5 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -29,6 +29,7 @@
 #include <signal.h>
 
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 #include "inf-child.h"
 #include "gdbthread.h"
 
@@ -52,7 +53,7 @@ inf_ptrace_follow_fork (struct target_ops *ops, int follow_child,
 	 infrun.c.  */
 
       if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
-	perror_with_name (("ptrace"));
+	throw_ptrace_error (("ptrace"));
     }
 
   return 0;
@@ -130,7 +131,7 @@ inf_ptrace_post_startup_inferior (struct target_ops *self, ptid_t pid)
   pe.pe_set_event |= PTRACE_FORK;
   if (ptrace (PT_SET_EVENT_MASK, ptid_get_pid (pid),
 	      (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
-    perror_with_name (("ptrace"));
+    throw_ptrace_error (("ptrace"));
 }
 
 #endif
@@ -197,7 +198,7 @@ inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty)
   errno = 0;
   ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
   if (errno != 0)
-    perror_with_name (("ptrace"));
+    throw_ptrace_error (("ptrace"));
 #else
   error (_("This system does not support attaching to a process"));
 #endif
@@ -226,7 +227,7 @@ inf_ptrace_post_attach (struct target_ops *self, int pid)
   pe.pe_set_event |= PTRACE_FORK;
   if (ptrace (PT_SET_EVENT_MASK, pid,
 	      (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
-    perror_with_name (("ptrace"));
+    throw_ptrace_error (("ptrace"));
 }
 
 #endif
@@ -260,7 +261,7 @@ inf_ptrace_detach (struct target_ops *ops, const char *args, int from_tty)
   errno = 0;
   ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, sig);
   if (errno != 0)
-    perror_with_name (("ptrace"));
+    throw_ptrace_error (("ptrace"));
 #else
   error (_("This system does not support detaching from a process"));
 #endif
@@ -356,7 +357,7 @@ inf_ptrace_resume (struct target_ops *ops,
   errno = 0;
   ptrace (request, pid, (PTRACE_TYPE_ARG3)1, gdb_signal_to_host (signal));
   if (errno != 0)
-    perror_with_name (("ptrace"));
+    throw_ptrace_error (("ptrace"));
 }
 
 /* Wait for the child specified by PTID to do something.  Return the
@@ -409,7 +410,7 @@ inf_ptrace_wait (struct target_ops *ops,
 
       if (ptrace (PT_GET_PROCESS_STATE, pid,
 		  (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
-	perror_with_name (("ptrace"));
+	throw_ptrace_error (("ptrace"));
 
       switch (pe.pe_report_event)
 	{
@@ -420,11 +421,11 @@ inf_ptrace_wait (struct target_ops *ops,
 	  /* Make sure the other end of the fork is stopped too.  */
 	  fpid = waitpid (pe.pe_other_pid, &status, 0);
 	  if (fpid == -1)
-	    perror_with_name (("waitpid"));
+	    throw_ptrace_error (("waitpid"));
 
 	  if (ptrace (PT_GET_PROCESS_STATE, fpid,
 		      (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
-	    perror_with_name (("ptrace"));
+	    throw_ptrace_error (("ptrace"));
 
 	  gdb_assert (pe.pe_report_event == PTRACE_FORK);
 	  gdb_assert (pe.pe_other_pid == pid);
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 627280e..20fe533 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -40,6 +40,7 @@
 #include "regset.h"
 #include "inf-child.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 #include "auxv.h"
 #include <sys/procfs.h>		/* for elf_gregset etc.  */
 #include "elf-bfd.h"		/* for elfcore_write_* */
@@ -425,7 +426,7 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child,
 	    {
 	      linux_disable_event_reporting (child_pid);
 	      if (ptrace (PTRACE_SINGLESTEP, child_pid, 0, 0) < 0)
-		perror_with_name (_("Couldn't do single step"));
+		throw_ptrace_error (_("Couldn't do single step"));
 	      if (my_waitpid (child_pid, &status, 0) < 0)
 		perror_with_name (_("Couldn't wait vfork process"));
 	    }
diff --git a/gdb/m32r-linux-nat.c b/gdb/m32r-linux-nat.c
index e5e867b..3ece241 100644
--- a/gdb/m32r-linux-nat.c
+++ b/gdb/m32r-linux-nat.c
@@ -22,6 +22,7 @@
 #include "gdbcore.h"
 #include "regcache.h"
 #include "linux-nat.h"
+#include "nat/ptrace-utils.h"
 #include "target.h"
 #include <sys/ptrace.h>
 #include <sys/user.h>
@@ -109,7 +110,7 @@ fetch_regs (struct regcache *regcache, int tid)
   elf_gregset_t regs;
 
   if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   supply_gregset (regcache, (const elf_gregset_t *) &regs);
 }
@@ -158,12 +159,12 @@ store_regs (const struct regcache *regcache, int tid, int regno)
   elf_gregset_t regs;
 
   if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   fill_gregset (regcache, &regs, regno);
 
   if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 }
 
 
diff --git a/gdb/m68kbsd-nat.c b/gdb/m68kbsd-nat.c
index 0b7ea21..2126dfd 100644
--- a/gdb/m68kbsd-nat.c
+++ b/gdb/m68kbsd-nat.c
@@ -28,6 +28,7 @@
 
 #include "m68k-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 static int
 m68kbsd_gregset_supplies_p (int regnum)
@@ -117,7 +118,7 @@ m68kbsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       m68kbsd_supply_gregset (regcache, &regs);
     }
@@ -128,7 +129,7 @@ m68kbsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       m68kbsd_supply_fpregset (regcache, &fpregs);
     }
@@ -147,13 +148,13 @@ m68kbsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't get registers"));
+        throw_ptrace_error (_("Couldn't get registers"));
 
       m68kbsd_collect_gregset (regcache, &regs, regnum);
 
       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	          (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't write registers"));
+        throw_ptrace_error (_("Couldn't write registers"));
     }
 
   if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
@@ -162,13 +163,13 @@ m68kbsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       m68kbsd_collect_fpregset (regcache, &fpregs, regnum);
 
       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't write floating point status"));
+	throw_ptrace_error (_("Couldn't write floating point status"));
     }
 }
 
diff --git a/gdb/m68klinux-nat.c b/gdb/m68klinux-nat.c
index 8f89d7b..ee95ffd 100644
--- a/gdb/m68klinux-nat.c
+++ b/gdb/m68klinux-nat.c
@@ -265,7 +265,7 @@ fetch_regs (struct regcache *regcache, int tid)
 	  return;
 	}
 
-      perror_with_name (_("Couldn't get registers"));
+      throw_ptrace_error (_("Couldn't get registers"));
     }
 
   supply_gregset (regcache, (const elf_gregset_t *) &regs);
@@ -280,12 +280,12 @@ store_regs (const struct regcache *regcache, int tid, int regno)
   elf_gregset_t regs;
 
   if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   fill_gregset (regcache, &regs, regno);
 
   if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 }
 
 #else
@@ -362,7 +362,7 @@ fetch_fpregs (struct regcache *regcache, int tid)
   elf_fpregset_t fpregs;
 
   if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
-    perror_with_name (_("Couldn't get floating point status"));
+    throw_ptrace_error (_("Couldn't get floating point status"));
 
   supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
 }
@@ -376,12 +376,12 @@ store_fpregs (const struct regcache *regcache, int tid, int regno)
   elf_fpregset_t fpregs;
 
   if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
-    perror_with_name (_("Couldn't get floating point status"));
+    throw_ptrace_error (_("Couldn't get floating point status"));
 
   fill_fpregset (regcache, &fpregs, regno);
 
   if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
-    perror_with_name (_("Couldn't write floating point status"));
+    throw_ptrace_error (_("Couldn't write floating point status"));
 }
 
 #else
diff --git a/gdb/m88kbsd-nat.c b/gdb/m88kbsd-nat.c
index 22c2a77..85ce83c 100644
--- a/gdb/m88kbsd-nat.c
+++ b/gdb/m88kbsd-nat.c
@@ -28,6 +28,7 @@
 
 #include "m88k-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
 
@@ -70,7 +71,7 @@ m88kbsd_fetch_inferior_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   m88kbsd_supply_gregset (regcache, &regs);
 }
@@ -86,13 +87,13 @@ m88kbsd_store_inferior_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   m88kbsd_collect_gregset (regcache, &regs, regnum);
 
   if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 }
 
 
diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index a36bb63..74b2f98 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -36,6 +36,7 @@
 #include <asm/ptrace.h>
 
 #include "nat/mips-linux-watch.h"
+#include "nat/ptrace-utils.h"
 
 #include "features/mips-linux.c"
 #include "features/mips-dsp-linux.c"
@@ -259,7 +260,7 @@ mips64_linux_regsets_fetch_registers (struct target_ops *ops,
 	      have_ptrace_regsets = 0;
 	      return;
 	    }
-	  perror_with_name (_("Couldn't get registers"));
+	  throw_ptrace_error (_("Couldn't get registers"));
 	}
 
       mips64_supply_gregset (regcache,
@@ -278,7 +279,7 @@ mips64_linux_regsets_fetch_registers (struct target_ops *ops,
 	      have_ptrace_regsets = 0;
 	      return;
 	    }
-	  perror_with_name (_("Couldn't get FP registers"));
+	  throw_ptrace_error (_("Couldn't get FP registers"));
 	}
 
       mips64_supply_fpregset (regcache,
@@ -341,12 +342,12 @@ mips64_linux_regsets_store_registers (struct target_ops *ops,
       mips64_elf_gregset_t regs;
 
       if (ptrace (PTRACE_GETREGS, tid, 0L, (PTRACE_TYPE_ARG3) &regs) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       mips64_fill_gregset (regcache, &regs, regno);
 
       if (ptrace (PTRACE_SETREGS, tid, 0L, (PTRACE_TYPE_ARG3) &regs) == -1)
-	perror_with_name (_("Couldn't set registers"));
+	throw_ptrace_error (_("Couldn't set registers"));
     }
 
   if (regno == -1 || is_fp)
@@ -355,13 +356,13 @@ mips64_linux_regsets_store_registers (struct target_ops *ops,
 
       if (ptrace (PTRACE_GETFPREGS, tid, 0L,
 		  (PTRACE_TYPE_ARG3) &fp_regs) == -1)
-	perror_with_name (_("Couldn't get FP registers"));
+	throw_ptrace_error (_("Couldn't get FP registers"));
 
       mips64_fill_fpregset (regcache, &fp_regs, regno);
 
       if (ptrace (PTRACE_SETFPREGS, tid, 0L,
 		  (PTRACE_TYPE_ARG3) &fp_regs) == -1)
-	perror_with_name (_("Couldn't set FP registers"));
+	throw_ptrace_error (_("Couldn't set FP registers"));
     }
 
   if (is_dsp)
@@ -446,7 +447,7 @@ mips_linux_read_description (struct target_ops *ops)
 	  have_dsp = 0;
 	  break;
 	default:
-	  perror_with_name (_("Couldn't check DSP support"));
+	  throw_ptrace_error (_("Couldn't check DSP support"));
 	  break;
 	}
     }
@@ -615,7 +616,7 @@ write_watchpoint_regs (void)
     {
       tid = ptid_get_lwp (lp->ptid);
       if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror) == -1)
-	perror_with_name (_("Couldn't write debug register"));
+	throw_ptrace_error (_("Couldn't write debug register"));
     }
   return 0;
 }
@@ -635,7 +636,7 @@ mips_linux_new_thread (struct lwp_info *lp)
 
   tid = ptid_get_lwp (lp->ptid);
   if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror) == -1)
-    perror_with_name (_("Couldn't write debug register"));
+    throw_ptrace_error (_("Couldn't write debug register"));
 }
 
 /* Target to_insert_watchpoint implementation.  Try to insert a new
diff --git a/gdb/mips64obsd-nat.c b/gdb/mips64obsd-nat.c
index 56d4fa9..e268edc 100644
--- a/gdb/mips64obsd-nat.c
+++ b/gdb/mips64obsd-nat.c
@@ -28,6 +28,7 @@
 
 #include "mips-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 #include "obsd-nat.h"
 
 /* Shorthand for some register numbers used below.  */
@@ -85,7 +86,7 @@ mips64obsd_fetch_inferior_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   mips64obsd_supply_gregset (regcache, &regs);
 }
@@ -101,13 +102,13 @@ mips64obsd_store_inferior_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   mips64obsd_collect_gregset (regcache, &regs, regnum);
 
   if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 }
 
 
diff --git a/gdb/mipsnbsd-nat.c b/gdb/mipsnbsd-nat.c
index 34dcd87..3ff1e96 100644
--- a/gdb/mipsnbsd-nat.c
+++ b/gdb/mipsnbsd-nat.c
@@ -29,6 +29,7 @@
 #include "mips-tdep.h"
 #include "mipsnbsd-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 /* Determine if PT_GETREGS fetches this register.  */
 static int
@@ -49,7 +50,7 @@ mipsnbsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
       
       mipsnbsd_supply_reg (regcache, (char *) &regs, regno);
       if (regno != -1)
@@ -63,7 +64,7 @@ mipsnbsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       mipsnbsd_supply_fpreg (regcache, (char *) &fpregs, regno);
     }
@@ -80,13 +81,13 @@ mipsnbsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       mipsnbsd_fill_reg (regcache, (char *) &regs, regno);
 
       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), 
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't write registers"));
+	throw_ptrace_error (_("Couldn't write registers"));
 
       if (regno != -1)
 	return;
@@ -99,13 +100,13 @@ mipsnbsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       mipsnbsd_fill_fpreg (regcache, (char *) &fpregs, regno);
 
       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't write floating point status"));
+	throw_ptrace_error (_("Couldn't write floating point status"));
     }
 }
 
diff --git a/gdb/nat/ptrace-utils.c b/gdb/nat/ptrace-utils.c
new file mode 100644
index 0000000..a3dc9b5
--- /dev/null
+++ b/gdb/nat/ptrace-utils.c
@@ -0,0 +1,29 @@
+/* Misc ptrace utils.
+
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "common-defs.h"
+#include "ptrace-utils.h"
+
+/* See ptrace-utils.h.  */
+
+void
+throw_ptrace_error (const char *string)
+{
+  perror_with_name (string);
+}
diff --git a/gdb/nat/ptrace-utils.h b/gdb/nat/ptrace-utils.h
new file mode 100644
index 0000000..886d156
--- /dev/null
+++ b/gdb/nat/ptrace-utils.h
@@ -0,0 +1,28 @@
+/* ptrace utilities.
+
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef PTRACE_UTILS_H
+#define PTRACE_UTILS_H
+
+/* Translates an error out of a ptrace call to a GDB exception.  */
+
+extern void throw_ptrace_error (const char *string)
+  ATTRIBUTE_NORETURN;
+
+#endif
diff --git a/gdb/obsd-nat.c b/gdb/obsd-nat.c
index 72ed10c..2208d3b 100644
--- a/gdb/obsd-nat.c
+++ b/gdb/obsd-nat.c
@@ -28,6 +28,7 @@
 
 #include "inf-child.h"
 #include "obsd-nat.h"
+#include "nat/ptrace-utils.h"
 
 /* OpenBSD 5.2 and later include rthreads which uses a thread model
    that maps userland threads directly onto kernel threads in a 1:1
@@ -58,7 +59,7 @@ obsd_update_thread_list (struct target_ops *ops)
   prune_threads ();
 
   if (ptrace (PT_GET_THREAD_FIRST, pid, (caddr_t)&pts, sizeof pts) == -1)
-    perror_with_name (("ptrace"));
+    throw_ptrace_error (("ptrace"));
 
   while (pts.pts_tid != -1)
     {
@@ -73,7 +74,7 @@ obsd_update_thread_list (struct target_ops *ops)
 	}
 
       if (ptrace (PT_GET_THREAD_NEXT, pid, (caddr_t)&pts, sizeof pts) == -1)
-	perror_with_name (("ptrace"));
+	throw_ptrace_error (("ptrace"));
     }
 }
 
@@ -123,7 +124,7 @@ obsd_wait (struct target_ops *ops,
       pid_t fpid;
 
       if (ptrace (PT_GET_PROCESS_STATE, pid, (caddr_t)&pe, sizeof pe) == -1)
-	perror_with_name (("ptrace"));
+	throw_ptrace_error (("ptrace"));
 
       switch (pe.pe_report_event)
 	{
@@ -138,7 +139,7 @@ obsd_wait (struct target_ops *ops,
 
 	  if (ptrace (PT_GET_PROCESS_STATE, fpid,
 		      (caddr_t)&pe, sizeof pe) == -1)
-	    perror_with_name (("ptrace"));
+	    throw_ptrace_error (("ptrace"));
 
 	  gdb_assert (pe.pe_report_event == PTRACE_FORK);
 	  gdb_assert (pe.pe_other_pid == pid);
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 88ca49e..779a84a 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -47,6 +47,7 @@
 #include "auxv.h"
 
 #include "nat/ppc-linux.h"
+#include "nat/ptrace-utils.h"
 
 /* Similarly for the hardware watchpoint support.  These requests are used
    when the PowerPC HWDEBUG ptrace interface is not available.  */
@@ -372,7 +373,7 @@ fetch_vsx_register (struct regcache *regcache, int tid, int regno)
 	  have_ptrace_getsetvsxregs = 0;
 	  return;
 	}
-      perror_with_name (_("Unable to fetch VSX register"));
+      throw_ptrace_error (_("Unable to fetch VSX register"));
     }
 
   regcache_raw_supply (regcache, regno,
@@ -401,7 +402,7 @@ fetch_altivec_register (struct regcache *regcache, int tid, int regno)
           have_ptrace_getvrregs = 0;
           return;
         }
-      perror_with_name (_("Unable to fetch AltiVec register"));
+      throw_ptrace_error (_("Unable to fetch AltiVec register"));
     }
  
   /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
@@ -439,7 +440,7 @@ get_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
             have_ptrace_getsetevrregs = 0;
           else
             /* Anything else needs to be reported.  */
-            perror_with_name (_("Unable to fetch SPE registers"));
+            throw_ptrace_error (_("Unable to fetch SPE registers"));
         }
     }
 
@@ -553,7 +554,7 @@ fetch_register (struct regcache *regcache, int tid, int regno)
           char message[128];
 	  xsnprintf (message, sizeof (message), "reading register %s (#%d)",
 		     gdbarch_register_name (gdbarch, regno), regno);
-	  perror_with_name (message);
+	  throw_ptrace_error (message);
 	}
       memcpy (&buf[bytes_transferred], &l, sizeof (l));
     }
@@ -634,7 +635,7 @@ fetch_vsx_registers (struct regcache *regcache, int tid)
 	  have_ptrace_getsetvsxregs = 0;
 	  return;
 	}
-      perror_with_name (_("Unable to fetch VSX registers"));
+      throw_ptrace_error (_("Unable to fetch VSX registers"));
     }
   supply_vsxregset (regcache, &regs);
 }
@@ -653,7 +654,7 @@ fetch_altivec_registers (struct regcache *regcache, int tid)
           have_ptrace_getvrregs = 0;
 	  return;
 	}
-      perror_with_name (_("Unable to fetch AltiVec registers"));
+      throw_ptrace_error (_("Unable to fetch AltiVec registers"));
     }
   supply_vrregset (regcache, &regs);
 }
@@ -664,7 +665,7 @@ fetch_altivec_registers (struct regcache *regcache, int tid)
    
    If the ptrace request does not exist, this function returns 0
    and properly sets the have_ptrace_* flag.  If the request fails,
-   this function calls perror_with_name.  Otherwise, if the request
+   this function calls throw_ptrace_error.  Otherwise, if the request
    succeeds, then the regcache gets filled and 1 is returned.  */
 static int
 fetch_all_gp_regs (struct regcache *regcache, int tid)
@@ -680,7 +681,7 @@ fetch_all_gp_regs (struct regcache *regcache, int tid)
           have_ptrace_getsetregs = 0;
           return 0;
         }
-      perror_with_name (_("Couldn't get general-purpose registers."));
+      throw_ptrace_error (_("Couldn't get general-purpose registers."));
     }
 
   supply_gregset (regcache, (const gdb_gregset_t *) &gregset);
@@ -718,7 +719,7 @@ fetch_gp_regs (struct regcache *regcache, int tid)
    
    If the ptrace request does not exist, this function returns 0
    and properly sets the have_ptrace_* flag.  If the request fails,
-   this function calls perror_with_name.  Otherwise, if the request
+   this function calls throw_ptrace_error.  Otherwise, if the request
    succeeds, then the regcache gets filled and 1 is returned.  */
 static int
 fetch_all_fp_regs (struct regcache *regcache, int tid)
@@ -732,7 +733,7 @@ fetch_all_fp_regs (struct regcache *regcache, int tid)
           have_ptrace_getsetfpregs = 0;
           return 0;
         }
-      perror_with_name (_("Couldn't get floating-point registers."));
+      throw_ptrace_error (_("Couldn't get floating-point registers."));
     }
 
   supply_fpregset (regcache, (const gdb_fpregset_t *) &fpregs);
@@ -842,7 +843,7 @@ store_vsx_register (const struct regcache *regcache, int tid, int regno)
 	  have_ptrace_getsetvsxregs = 0;
 	  return;
 	}
-      perror_with_name (_("Unable to fetch VSX register"));
+      throw_ptrace_error (_("Unable to fetch VSX register"));
     }
 
   regcache_raw_collect (regcache, regno, regs +
@@ -850,7 +851,7 @@ store_vsx_register (const struct regcache *regcache, int tid, int regno)
 
   ret = ptrace (PTRACE_SETVSXREGS, tid, 0, &regs);
   if (ret < 0)
-    perror_with_name (_("Unable to store VSX register"));
+    throw_ptrace_error (_("Unable to store VSX register"));
 }
 
 /* Store one register.  */
@@ -872,7 +873,7 @@ store_altivec_register (const struct regcache *regcache, int tid, int regno)
           have_ptrace_getvrregs = 0;
           return;
         }
-      perror_with_name (_("Unable to fetch AltiVec register"));
+      throw_ptrace_error (_("Unable to fetch AltiVec register"));
     }
 
   /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
@@ -886,7 +887,7 @@ store_altivec_register (const struct regcache *regcache, int tid, int regno)
 
   ret = ptrace (PTRACE_SETVRREGS, tid, 0, &regs);
   if (ret < 0)
-    perror_with_name (_("Unable to store AltiVec register"));
+    throw_ptrace_error (_("Unable to store AltiVec register"));
 }
 
 /* Assuming TID referrs to an SPE process, set the top halves of TID's
@@ -913,7 +914,7 @@ set_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
             have_ptrace_getsetevrregs = 0;
           else
             /* Anything else needs to be reported.  */
-            perror_with_name (_("Unable to set SPE registers"));
+            throw_ptrace_error (_("Unable to set SPE registers"));
         }
     }
 }
@@ -1047,7 +1048,7 @@ store_register (const struct regcache *regcache, int tid, int regno)
           char message[128];
 	  xsnprintf (message, sizeof (message), "writing register %s (#%d)",
 		     gdbarch_register_name (gdbarch, regno), regno);
-	  perror_with_name (message);
+	  throw_ptrace_error (message);
 	}
     }
 }
@@ -1102,13 +1103,13 @@ store_vsx_registers (const struct regcache *regcache, int tid)
 	  have_ptrace_getsetvsxregs = 0;
 	  return;
 	}
-      perror_with_name (_("Couldn't get VSX registers"));
+      throw_ptrace_error (_("Couldn't get VSX registers"));
     }
 
   fill_vsxregset (regcache, &regs);
 
   if (ptrace (PTRACE_SETVSXREGS, tid, 0, &regs) < 0)
-    perror_with_name (_("Couldn't write VSX registers"));
+    throw_ptrace_error (_("Couldn't write VSX registers"));
 }
 
 static void
@@ -1125,13 +1126,13 @@ store_altivec_registers (const struct regcache *regcache, int tid)
           have_ptrace_getvrregs = 0;
           return;
         }
-      perror_with_name (_("Couldn't get AltiVec registers"));
+      throw_ptrace_error (_("Couldn't get AltiVec registers"));
     }
 
   fill_vrregset (regcache, &regs);
   
   if (ptrace (PTRACE_SETVRREGS, tid, 0, &regs) < 0)
-    perror_with_name (_("Couldn't write AltiVec registers"));
+    throw_ptrace_error (_("Couldn't write AltiVec registers"));
 }
 
 /* This function actually issues the request to ptrace, telling
@@ -1140,7 +1141,7 @@ store_altivec_registers (const struct regcache *regcache, int tid)
    
    If the ptrace request does not exist, this function returns 0
    and properly sets the have_ptrace_* flag.  If the request fails,
-   this function calls perror_with_name.  Otherwise, if the request
+   this function calls throw_ptrace_error.  Otherwise, if the request
    succeeds, then the regcache is stored and 1 is returned.  */
 static int
 store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
@@ -1156,7 +1157,7 @@ store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
           have_ptrace_getsetregs = 0;
           return 0;
         }
-      perror_with_name (_("Couldn't get general-purpose registers."));
+      throw_ptrace_error (_("Couldn't get general-purpose registers."));
     }
 
   fill_gregset (regcache, &gregset, regno);
@@ -1168,7 +1169,7 @@ store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
           have_ptrace_getsetregs = 0;
           return 0;
         }
-      perror_with_name (_("Couldn't set general-purpose registers."));
+      throw_ptrace_error (_("Couldn't set general-purpose registers."));
     }
 
   return 1;
@@ -1204,7 +1205,7 @@ store_gp_regs (const struct regcache *regcache, int tid, int regno)
    
    If the ptrace request does not exist, this function returns 0
    and properly sets the have_ptrace_* flag.  If the request fails,
-   this function calls perror_with_name.  Otherwise, if the request
+   this function calls throw_ptrace_error.  Otherwise, if the request
    succeeds, then the regcache is stored and 1 is returned.  */
 static int
 store_all_fp_regs (const struct regcache *regcache, int tid, int regno)
@@ -1218,7 +1219,7 @@ store_all_fp_regs (const struct regcache *regcache, int tid, int regno)
           have_ptrace_getsetfpregs = 0;
           return 0;
         }
-      perror_with_name (_("Couldn't get floating-point registers."));
+      throw_ptrace_error (_("Couldn't get floating-point registers."));
     }
 
   fill_fpregset (regcache, &fpregs, regno);
@@ -1230,7 +1231,7 @@ store_all_fp_regs (const struct regcache *regcache, int tid, int regno)
           have_ptrace_getsetfpregs = 0;
           return 0;
         }
-      perror_with_name (_("Couldn't set floating-point registers."));
+      throw_ptrace_error (_("Couldn't set floating-point registers."));
     }
 
   return 1;
@@ -1559,7 +1560,7 @@ hwdebug_insert_point (struct ppc_hw_breakpoint *b, int tid)
   errno = 0;
   slot = ptrace (PPC_PTRACE_SETHWDEBUG, tid, 0, p);
   if (slot < 0)
-    perror_with_name (_("Unexpected error setting breakpoint or watchpoint"));
+    throw_ptrace_error (_("Unexpected error setting breakpoint or watchpoint"));
 
   /* Everything went fine, so we have to register this *point.  */
   t = hwdebug_find_thread_points_by_tid (tid, 1);
@@ -1606,7 +1607,7 @@ hwdebug_remove_point (struct ppc_hw_breakpoint *b, int tid)
   errno = 0;
   if (ptrace (PPC_PTRACE_DELHWDEBUG, tid, 0, hw_breaks[i].slot) < 0)
     if (errno != ENOENT)
-      perror_with_name (_("Unexpected error deleting "
+      throw_ptrace_error (_("Unexpected error deleting "
 			  "breakpoint or watchpoint"));
 
   xfree (hw_breaks[i].hw_break);
@@ -2419,7 +2420,7 @@ ppc_linux_read_description (struct target_ops *ops)
       /* EIO means that the PTRACE_GETEVRREGS request isn't supported.
 	 Anything else needs to be reported.  */
       else if (errno != EIO)
-	perror_with_name (_("Unable to fetch SPE registers"));
+	throw_ptrace_error (_("Unable to fetch SPE registers"));
     }
 
   if (have_ptrace_getsetvsxregs)
@@ -2432,7 +2433,7 @@ ppc_linux_read_description (struct target_ops *ops)
       /* EIO means that the PTRACE_GETVSXREGS request isn't supported.
 	 Anything else needs to be reported.  */
       else if (errno != EIO)
-	perror_with_name (_("Unable to fetch VSX registers"));
+	throw_ptrace_error (_("Unable to fetch VSX registers"));
     }
 
   if (have_ptrace_getvrregs)
@@ -2445,7 +2446,7 @@ ppc_linux_read_description (struct target_ops *ops)
       /* EIO means that the PTRACE_GETVRREGS request isn't supported.
 	 Anything else needs to be reported.  */
       else if (errno != EIO)
-	perror_with_name (_("Unable to fetch AltiVec registers"));
+	throw_ptrace_error (_("Unable to fetch AltiVec registers"));
     }
 
   /* Power ISA 2.05 (implemented by Power 6 and newer processors) increases
diff --git a/gdb/ppcfbsd-nat.c b/gdb/ppcfbsd-nat.c
index 778b4bb..544fe7a 100644
--- a/gdb/ppcfbsd-nat.c
+++ b/gdb/ppcfbsd-nat.c
@@ -35,6 +35,7 @@
 #include "ppc-tdep.h"
 #include "ppcfbsd-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 #include "bsd-kvm.h"
 
 /* Fill GDB's register array with the general-purpose register values
@@ -123,7 +124,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   supply_gregset (regcache, &regs);
 
@@ -134,7 +135,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get FP registers"));
+	throw_ptrace_error (_("Couldn't get FP registers"));
 
       ppc_supply_fpregset (fpregset, regcache, regno, &fpregs, sizeof fpregs);
     }
@@ -151,13 +152,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   fill_gregset (regcache, &regs, regno);
 
   if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 
   if (regno == -1 || getfpregs_supplies (get_regcache_arch (regcache), regno))
     {
@@ -165,13 +166,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get FP registers"));
+	throw_ptrace_error (_("Couldn't get FP registers"));
 
       fill_fpregset (regcache, &fpregs, regno);
 
       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't set FP registers"));
+	throw_ptrace_error (_("Couldn't set FP registers"));
     }
 }
 
diff --git a/gdb/ppcnbsd-nat.c b/gdb/ppcnbsd-nat.c
index 59195c0..bc7e852 100644
--- a/gdb/ppcnbsd-nat.c
+++ b/gdb/ppcnbsd-nat.c
@@ -35,6 +35,7 @@
 #include "ppcnbsd-tdep.h"
 #include "bsd-kvm.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 /* Returns true if PT_GETREGS fetches this register.  */
 
@@ -88,7 +89,7 @@ ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-        perror_with_name (_("Couldn't get registers"));
+        throw_ptrace_error (_("Couldn't get registers"));
 
       ppc_supply_gregset (&ppcnbsd_gregset, regcache,
 			  regnum, &regs, sizeof regs);
@@ -100,7 +101,7 @@ ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get FP registers"));
+	throw_ptrace_error (_("Couldn't get FP registers"));
 
       ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
 			   regnum, &fpregs, sizeof fpregs);
@@ -119,14 +120,14 @@ ppcnbsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       ppc_collect_gregset (&ppcnbsd_gregset, regcache,
 			   regnum, &regs, sizeof regs);
 
       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't write registers"));
+	throw_ptrace_error (_("Couldn't write registers"));
     }
 
   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
@@ -135,14 +136,14 @@ ppcnbsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get FP registers"));
+	throw_ptrace_error (_("Couldn't get FP registers"));
 
       ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
 			    regnum, &fpregs, sizeof fpregs);
 
       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't set FP registers"));
+	throw_ptrace_error (_("Couldn't set FP registers"));
     }
 }
 
diff --git a/gdb/ppcobsd-nat.c b/gdb/ppcobsd-nat.c
index eef7305..b1f3654 100644
--- a/gdb/ppcobsd-nat.c
+++ b/gdb/ppcobsd-nat.c
@@ -32,6 +32,7 @@
 #include "ppc-tdep.h"
 #include "ppcobsd-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 #include "obsd-nat.h"
 #include "bsd-kvm.h"
 
@@ -78,7 +79,7 @@ ppcobsd_fetch_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   ppc_supply_gregset (&ppcobsd_gregset, regcache, -1,
 		      &regs, sizeof regs);
@@ -95,7 +96,7 @@ ppcobsd_fetch_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       ppc_supply_fpregset (&ppcobsd_fpregset, regcache, -1,
 			   &fpregs, sizeof fpregs);
@@ -114,7 +115,7 @@ ppcobsd_store_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   ppc_collect_gregset (&ppcobsd_gregset, regcache,
 		       regnum, &regs, sizeof regs);
@@ -125,7 +126,7 @@ ppcobsd_store_registers (struct target_ops *ops,
 
   if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 
 #ifdef PT_GETFPREGS
   if (regnum == -1
@@ -135,14 +136,14 @@ ppcobsd_store_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       ppc_collect_fpregset (&ppcobsd_fpregset, regcache,
 			    regnum, &fpregs, sizeof fpregs);
 
       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't write floating point status"));
+	throw_ptrace_error (_("Couldn't write floating point status"));
     }
 #endif
 }
diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c
index 8cdd86f..3c48a73 100644
--- a/gdb/rs6000-nat.c
+++ b/gdb/rs6000-nat.c
@@ -30,6 +30,7 @@
 #include "arch-utils.h"
 #include "inf-child.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 #include "ppc-tdep.h"
 #include "rs6000-tdep.h"
 #include "rs6000-aix-tdep.h"
@@ -608,7 +609,7 @@ rs6000_ptrace_ldinfo (ptid_t ptid)
 	break; /* Success, we got the entire ld_info data.  */
 
       if (errno != ENOMEM)
-	perror_with_name (_("ptrace ldinfo"));
+	throw_ptrace_error (_("ptrace ldinfo"));
 
       /* ldi is not big enough.  Double it and try again.  */
       ldi_size *= 2;
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index 367b610..4837738 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -213,7 +213,7 @@ fetch_regs (struct regcache *regcache, int tid)
   parea.process_addr = (addr_t) &regs;
   parea.kernel_addr = offsetof (struct user_regs_struct, psw);
   if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   supply_gregset (regcache, (const gregset_t *) &regs);
 }
@@ -230,12 +230,12 @@ store_regs (const struct regcache *regcache, int tid, int regnum)
   parea.process_addr = (addr_t) &regs;
   parea.kernel_addr = offsetof (struct user_regs_struct, psw);
   if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   fill_gregset (regcache, &regs, regnum);
 
   if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 }
 
 /* Fetch all floating-point registers from process/thread TID and store
@@ -250,7 +250,7 @@ fetch_fpregs (struct regcache *regcache, int tid)
   parea.process_addr = (addr_t) &fpregs;
   parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
   if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
-    perror_with_name (_("Couldn't get floating point status"));
+    throw_ptrace_error (_("Couldn't get floating point status"));
 
   supply_fpregset (regcache, (const fpregset_t *) &fpregs);
 }
@@ -267,12 +267,12 @@ store_fpregs (const struct regcache *regcache, int tid, int regnum)
   parea.process_addr = (addr_t) &fpregs;
   parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
   if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
-    perror_with_name (_("Couldn't get floating point status"));
+    throw_ptrace_error (_("Couldn't get floating point status"));
 
   fill_fpregset (regcache, &fpregs, regnum);
 
   if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
-    perror_with_name (_("Couldn't write floating point status"));
+    throw_ptrace_error (_("Couldn't write floating point status"));
 }
 
 /* Fetch all registers in the kernel's register set whose number is
@@ -294,7 +294,7 @@ fetch_regset (struct regcache *regcache, int tid,
       if (errno == ENODATA)
 	regcache_supply_regset (regset, regcache, -1, NULL, regsize);
       else
-	perror_with_name (_("Couldn't get register set"));
+	throw_ptrace_error (_("Couldn't get register set"));
     }
   else
     regcache_supply_regset (regset, regcache, -1, buf, regsize);
@@ -314,12 +314,12 @@ store_regset (struct regcache *regcache, int tid,
   iov.iov_len = regsize;
 
   if (ptrace (PTRACE_GETREGSET, tid, (long) regset_id, (long) &iov) < 0)
-    perror_with_name (_("Couldn't get register set"));
+    throw_ptrace_error (_("Couldn't get register set"));
 
   regcache_collect_regset (regset, regcache, -1, buf, regsize);
 
   if (ptrace (PTRACE_SETREGSET, tid, (long) regset_id, (long) &iov) < 0)
-    perror_with_name (_("Couldn't set register set"));
+    throw_ptrace_error (_("Couldn't set register set"));
 }
 
 /* Check whether the kernel provides a register set with number REGSET
@@ -449,7 +449,7 @@ s390_stopped_by_watchpoint (struct target_ops *ops)
   parea.process_addr = (addr_t) & per_lowcore;
   parea.kernel_addr = offsetof (struct user_regs_struct, per_info.lowcore);
   if (ptrace (PTRACE_PEEKUSR_AREA, s390_inferior_tid (), &parea) < 0)
-    perror_with_name (_("Couldn't retrieve watchpoint status"));
+    throw_ptrace_error (_("Couldn't retrieve watchpoint status"));
 
   result = (per_lowcore.perc_storage_alteration == 1
 	    && per_lowcore.perc_store_real_address == 0);
@@ -459,7 +459,7 @@ s390_stopped_by_watchpoint (struct target_ops *ops)
       /* Do not report this watchpoint again.  */
       memset (&per_lowcore, 0, sizeof (per_lowcore));
       if (ptrace (PTRACE_POKEUSR_AREA, s390_inferior_tid (), &parea) < 0)
-	perror_with_name (_("Couldn't clear watchpoint status"));
+	throw_ptrace_error (_("Couldn't clear watchpoint status"));
     }
 
   return result;
@@ -490,7 +490,7 @@ s390_fix_watch_points (struct lwp_info *lp)
   parea.process_addr = (addr_t) & per_info;
   parea.kernel_addr = offsetof (struct user_regs_struct, per_info);
   if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea) < 0)
-    perror_with_name (_("Couldn't retrieve watchpoint status"));
+    throw_ptrace_error (_("Couldn't retrieve watchpoint status"));
 
   if (watch_base)
     {
@@ -506,7 +506,7 @@ s390_fix_watch_points (struct lwp_info *lp)
   per_info.ending_addr = watch_hi_addr;
 
   if (ptrace (PTRACE_POKEUSR_AREA, tid, &parea) < 0)
-    perror_with_name (_("Couldn't modify watchpoint status"));
+    throw_ptrace_error (_("Couldn't modify watchpoint status"));
 }
 
 static int
diff --git a/gdb/shnbsd-nat.c b/gdb/shnbsd-nat.c
index e0ed5e6..56e5943 100644
--- a/gdb/shnbsd-nat.c
+++ b/gdb/shnbsd-nat.c
@@ -28,6 +28,7 @@
 
 #include "sh-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 #include "regcache.h"
 
 
@@ -51,7 +52,7 @@ shnbsd_fetch_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       sh_corefile_supply_regset (&sh_corefile_gregset, regcache, regno,
 				 (char *) &inferior_registers,
@@ -72,7 +73,7 @@ shnbsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       sh_corefile_collect_regset (&sh_corefile_gregset, regcache, regno,
 				  (char *) &inferior_registers,
@@ -80,7 +81,7 @@ shnbsd_store_inferior_registers (struct target_ops *ops,
 
       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
-	perror_with_name (_("Couldn't set registers"));
+	throw_ptrace_error (_("Couldn't set registers"));
 
       if (regno != -1)
 	return;
diff --git a/gdb/sparc-nat.c b/gdb/sparc-nat.c
index f1d82e5..152f6bb 100644
--- a/gdb/sparc-nat.c
+++ b/gdb/sparc-nat.c
@@ -32,6 +32,7 @@
 #include "sparc-tdep.h"
 #include "sparc-nat.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 /* With some trickery we can use the code in this file for most (if
    not all) ptrace(2) based SPARC systems, which includes SunOS 4,
@@ -170,7 +171,7 @@ sparc_fetch_inferior_registers (struct target_ops *ops,
       gregset_t regs;
 
       if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       sparc_supply_gregset (sparc_gregmap, regcache, -1, &regs);
       if (regnum != -1)
@@ -182,7 +183,7 @@ sparc_fetch_inferior_registers (struct target_ops *ops,
       fpregset_t fpregs;
 
       if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating point status"));
+	throw_ptrace_error (_("Couldn't get floating point status"));
 
       sparc_supply_fpregset (sparc_fpregmap, regcache, -1, &fpregs);
     }
@@ -206,12 +207,12 @@ sparc_store_inferior_registers (struct target_ops *ops,
       gregset_t regs;
 
       if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't get registers"));
+	throw_ptrace_error (_("Couldn't get registers"));
 
       sparc_collect_gregset (sparc_gregmap, regcache, regnum, &regs);
 
       if (ptrace (PTRACE_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-	perror_with_name (_("Couldn't write registers"));
+	throw_ptrace_error (_("Couldn't write registers"));
 
       /* Deal with the stack regs.  */
       if (regnum == -1 || regnum == SPARC_SP_REGNUM
@@ -232,7 +233,7 @@ sparc_store_inferior_registers (struct target_ops *ops,
       fpregset_t fpregs, saved_fpregs;
 
       if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	perror_with_name (_("Couldn't get floating-point registers"));
+	throw_ptrace_error (_("Couldn't get floating-point registers"));
 
       memcpy (&saved_fpregs, &fpregs, sizeof (fpregs));
       sparc_collect_fpregset (sparc_fpregmap, regcache, regnum, &fpregs);
@@ -245,7 +246,7 @@ sparc_store_inferior_registers (struct target_ops *ops,
 	{
 	  if (ptrace (PTRACE_SETFPREGS, pid,
 		      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
-	    perror_with_name (_("Couldn't write floating-point registers"));
+	    throw_ptrace_error (_("Couldn't write floating-point registers"));
 	}
 
       if (regnum != -1)
@@ -291,7 +292,7 @@ sparc_xfer_wcookie (struct target_ops *ops, enum target_object object,
     if (ptrace (PT_WCOOKIE, pid, (PTRACE_TYPE_ARG3) &wcookie, 0) == -1)
       {
 	if (errno != EINVAL)
-	  perror_with_name (_("Couldn't get StackGhost cookie"));
+	  throw_ptrace_error (_("Couldn't get StackGhost cookie"));
 
 	/* Although PT_WCOOKIE is defined on OpenBSD 3.1 and later,
 	   the request wasn't implemented until after OpenBSD 3.4.  If
diff --git a/gdb/spu-linux-nat.c b/gdb/spu-linux-nat.c
index b0942a9..cf0f4df 100644
--- a/gdb/spu-linux-nat.c
+++ b/gdb/spu-linux-nat.c
@@ -24,6 +24,7 @@
 #include "inferior.h"
 #include "inf-child.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 #include "regcache.h"
 #include "symfile.h"
 #include "gdb_wait.h"
@@ -77,7 +78,7 @@ fetch_ppc_register (int regno)
     {
       char mess[128];
       xsnprintf (mess, sizeof mess, "reading PPC register #%d", regno);
-      perror_with_name (_(mess));
+      throw_ptrace_error (_(mess));
     }
 
   return (ULONGEST) (unsigned long) res;
diff --git a/gdb/tilegx-linux-nat.c b/gdb/tilegx-linux-nat.c
index b8f0c76..68c2391 100644
--- a/gdb/tilegx-linux-nat.c
+++ b/gdb/tilegx-linux-nat.c
@@ -133,7 +133,7 @@ fetch_inferior_registers (struct target_ops *ops,
     tid = ptid_get_pid (inferior_ptid);
 
   if (ptrace (PTRACE_GETREGS, tid, 0, (PTRACE_TYPE_ARG3) &regs) < 0)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   supply_gregset (regcache, (const elf_gregset_t *)&regs);
 }
@@ -153,12 +153,12 @@ store_inferior_registers (struct target_ops *ops,
     tid = ptid_get_pid (inferior_ptid);
 
   if (ptrace (PTRACE_GETREGS, tid, 0, (PTRACE_TYPE_ARG3) &regs) < 0)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   fill_gregset (regcache, &regs, regnum);
 
   if (ptrace (PTRACE_SETREGS, tid, 0, (PTRACE_TYPE_ARG3) &regs) < 0)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 }
 
 
diff --git a/gdb/vaxbsd-nat.c b/gdb/vaxbsd-nat.c
index 866b958..7caae30 100644
--- a/gdb/vaxbsd-nat.c
+++ b/gdb/vaxbsd-nat.c
@@ -28,6 +28,7 @@
 
 #include "vax-tdep.h"
 #include "inf-ptrace.h"
+#include "nat/ptrace-utils.h"
 
 /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
 
@@ -70,7 +71,7 @@ vaxbsd_fetch_inferior_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   vaxbsd_supply_gregset (regcache, &regs);
 }
@@ -86,13 +87,13 @@ vaxbsd_store_inferior_registers (struct target_ops *ops,
 
   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't get registers"));
+    throw_ptrace_error (_("Couldn't get registers"));
 
   vaxbsd_collect_gregset (regcache, &regs, regnum);
 
   if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
-    perror_with_name (_("Couldn't write registers"));
+    throw_ptrace_error (_("Couldn't write registers"));
 }
 
 
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
index 26ae0b8..d184e41 100644
--- a/gdb/x86-linux-nat.c
+++ b/gdb/x86-linux-nat.c
@@ -28,6 +28,7 @@
 
 #include "x86-nat.h"
 #include "linux-nat.h"
+#include "nat/ptrace-utils.h"
 #ifndef __x86_64__
 #include "i386-linux-nat.h"
 #endif
@@ -78,7 +79,7 @@ x86_linux_dr_get (ptid_t ptid, int regnum)
   value = ptrace (PTRACE_PEEKUSER, tid, u_debugreg_offset (regnum), 0);
 
   if (errno != 0)
-    perror_with_name (_("Couldn't read debug register"));
+    throw_ptrace_error (_("Couldn't read debug register"));
 
   return value;
 }
@@ -96,7 +97,7 @@ x86_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
   errno = 0;
   ptrace (PTRACE_POKEUSER, tid, u_debugreg_offset (regnum), value);
   if (errno != 0)
-    perror_with_name (_("Couldn't write debug register"));
+    throw_ptrace_error (_("Couldn't write debug register"));
 }
 
 /* Return the inferior's debug register REGNUM.  */
@@ -323,7 +324,7 @@ x86_linux_read_description (struct target_ops *ops)
     cs = ptrace (PTRACE_PEEKUSER, tid,
 		 offsetof (struct user_regs_struct, cs), 0);
     if (errno != 0)
-      perror_with_name (_("Couldn't get CS register"));
+      throw_ptrace_error (_("Couldn't get CS register"));
 
     is_64bit = cs == AMD64_LINUX_USER64_CS;
 
@@ -332,7 +333,7 @@ x86_linux_read_description (struct target_ops *ops)
     ds = ptrace (PTRACE_PEEKUSER, tid,
 		 offsetof (struct user_regs_struct, ds), 0);
     if (errno != 0)
-      perror_with_name (_("Couldn't get DS register"));
+      throw_ptrace_error (_("Couldn't get DS register"));
 
     is_x32 = ds == AMD64_LINUX_X32_DS;
 
diff --git a/gdb/xtensa-linux-nat.c b/gdb/xtensa-linux-nat.c
index 921bc99..428fe37 100644
--- a/gdb/xtensa-linux-nat.c
+++ b/gdb/xtensa-linux-nat.c
@@ -189,7 +189,7 @@ fetch_gregs (struct regcache *regcache, int regnum)
   
   if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
     {
-      perror_with_name (_("Couldn't get registers"));
+      throw_ptrace_error (_("Couldn't get registers"));
       return;
     }
  
@@ -208,7 +208,7 @@ store_gregs (struct regcache *regcache, int regnum)
 
   if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
     {
-      perror_with_name (_("Couldn't get registers"));
+      throw_ptrace_error (_("Couldn't get registers"));
       return;
     }
 
@@ -216,7 +216,7 @@ store_gregs (struct regcache *regcache, int regnum)
 
   if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
     {
-      perror_with_name (_("Couldn't write registers"));
+      throw_ptrace_error (_("Couldn't write registers"));
       return;
     }
 }
@@ -235,7 +235,7 @@ fetch_xtregs (struct regcache *regcache, int regnum)
   char xtregs [XTENSA_ELF_XTREG_SIZE];
 
   if (ptrace (PTRACE_GETXTREGS, tid, 0, (long)&xtregs) < 0)
-    perror_with_name (_("Couldn't get extended registers"));
+    throw_ptrace_error (_("Couldn't get extended registers"));
 
   for (ptr = xtensa_regmap_table; ptr->name; ptr++)
     if (regnum == ptr->gdb_regnum || regnum == -1)
@@ -251,7 +251,7 @@ store_xtregs (struct regcache *regcache, int regnum)
   char xtregs [XTENSA_ELF_XTREG_SIZE];
 
   if (ptrace (PTRACE_GETXTREGS, tid, 0, (long)&xtregs) < 0)
-    perror_with_name (_("Couldn't get extended registers"));
+    throw_ptrace_error (_("Couldn't get extended registers"));
 
   for (ptr = xtensa_regmap_table; ptr->name; ptr++)
     if (regnum == ptr->gdb_regnum || regnum == -1)
@@ -259,7 +259,7 @@ store_xtregs (struct regcache *regcache, int regnum)
 			    xtregs + ptr->ptrace_offset);
 
   if (ptrace (PTRACE_SETXTREGS, tid, 0, (long)&xtregs) < 0)
-    perror_with_name (_("Couldn't write extended registers"));
+    throw_ptrace_error (_("Couldn't write extended registers"));
 }
 
 void
