]> granicus.if.org Git - strace/commitdiff
Replace many more bare ptrace calls with calls to wrappers
authorDenys Vlasenko <dvlasenk@redhat.com>
Tue, 24 Feb 2009 15:17:53 +0000 (15:17 +0000)
committerDenys Vlasenko <dvlasenk@redhat.com>
Tue, 24 Feb 2009 15:17:53 +0000 (15:17 +0000)
which do proper error-checking and set tcp->ptrace_errno.
In some cases, missing error checking is added.
Error handling for trace_syscall() failures and other cases
where tcp->ptrace_errno is nonzero is cleaned up a bit
and made more verbose if we see error other than ESRC.
Some comments are added or expanded.
* defs.h: Declare ptrace_cmds[]. Modify do_ptrace
declaration (last parameter is long, not void *).
* process.c: Make ptrace_cmds[] non-static.
(change_syscall): Use do_ptrace() instead of bare ptrace().
* signal.c: Use do_ptrace() instead of bare ptrace().
* strace.c: Update trace_syscall() failure handling.
* syscall.c: Use do_ptrace() instead of bare ptrace().
* util.c: Use do_ptrace() instead of bare ptrace().
Update do_ptrace() wrapper.
(str_PTRACE_xxx): New function - helper returning "PTRACE_xxx".
(do_ptrace_peekdata): New function - wrapper for PTRACE_PEEKDATA
(do_ptrace5): New function - wrapper for 5-argument ptrace calls.

ChangeLog
defs.h
process.c
signal.c
strace.c
syscall.c
util.c

index e7886a028c0ed57f0635cba44bbd5304ea33db8d..d833dd59c5ebf83499b7a951018f71000bbd9e40 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2009-02-24  Denys Vlasenko  <dvlasenk@redhat.com>
+
+       Replace many more bare ptrace calls with calls to wrappers
+       which do proper error-checking and set tcp->ptrace_errno.
+       In some cases, missing error checking is added.
+       Error handling for trace_syscall() failures and other cases
+       where tcp->ptrace_errno is nonzero is cleaned up a bit
+       and made more verbose if we see error other than ESRC.
+       Some comments are added or expanded.
+       * defs.h: Declare ptrace_cmds[]. Modify do_ptrace
+       declaration (last parameter is long, not void *).
+       * process.c: Make ptrace_cmds[] non-static.
+       (change_syscall): Use do_ptrace() instead of bare ptrace().
+       * signal.c: Use do_ptrace() instead of bare ptrace().
+       * strace.c: Update trace_syscall() failure handling.
+       * syscall.c: Use do_ptrace() instead of bare ptrace().
+       * util.c: Use do_ptrace() instead of bare ptrace().
+       Update do_ptrace() wrapper.
+       (str_PTRACE_xxx): New function - helper returning "PTRACE_xxx".
+       (do_ptrace_peekdata): New function - wrapper for PTRACE_PEEKDATA
+       (do_ptrace5): New function - wrapper for 5-argument ptrace calls.
+
 2009-02-24  Denys Vlasenko  <dvlasenk@redhat.com>
 
        * process.c: Indent preprocessor directives so that nesting
diff --git a/defs.h b/defs.h
index 7b327af6cf227493642d4df785d59d25026b815f..7c88a1c4a075c1028562056918fc8d9f7d80b85f 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -424,6 +424,7 @@ extern const struct xlat open_mode_flags[];
 extern const struct xlat addrfams[];
 extern const struct xlat struct_user_offsets[];
 extern const struct xlat open_access_modes[];
+extern const struct xlat ptrace_cmds[];
 
 /* Format of syscall return values */
 #define RVAL_DECIMAL   000     /* decimal format */
@@ -485,7 +486,7 @@ extern void set_overhead P((int));
 extern void qualify P((char *));
 extern int get_scno P((struct tcb *));
 extern long known_scno P((struct tcb *));
-extern long do_ptrace P((int request, struct tcb *tcp, void *addr, void *data));
+extern long do_ptrace P((int request, struct tcb *tcp, void *addr, long data));
 extern int ptrace_restart P((int request, struct tcb *tcp, int sig));
 extern int trace_syscall P((struct tcb *));
 extern int count_syscall P((struct tcb *, struct timeval *));
index 29e57d5e97d9f3e28d6ee564d836156889f62529..cf538808170632eb9ae7261a3f2e5030832ecc23 100644 (file)
--- a/process.c
+++ b/process.c
@@ -771,7 +771,7 @@ change_syscall(struct tcb *tcp, int new)
 #  define PTRACE_SET_SYSCALL 23
 # endif
 
-       if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
+       if (do_ptrace(PTRACE_SET_SYSCALL, tcp, NULL, new) != 0)
                return -1;
 
        return 0;
@@ -2276,7 +2276,7 @@ struct tcb *tcp;
 
 #ifndef SVR4
 
-static const struct xlat ptrace_cmds[] = {
+const struct xlat ptrace_cmds[] = {
 # ifndef FREEBSD
        { PTRACE_TRACEME,       "PTRACE_TRACEME"        },
        { PTRACE_PEEKTEXT,      "PTRACE_PEEKTEXT",      },
index 9f4edd91c278515997c08b32e975cfd53387844d..179b7f4be14e016b9160255720f946ad6a323720 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -1409,14 +1409,13 @@ struct tcb *tcp;
        struct regs regs;
        m_siginfo_t si;
 
-       if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
-               perror("sigreturn: PTRACE_GETREGS ");
+       if (do_ptrace(PTRACE_GETREGS, tcp, (char *)&regs, 0) < 0) {
                return 0;
        }
-       if(entering(tcp)) {
+       if (entering(tcp)) {
                tcp->u_arg[0] = 0;
                i1 = regs.r_o1;
-               if(umove(tcp, i1, &si) < 0) {
+               if (umove(tcp, i1, &si) < 0) {
                        perror("sigreturn: umove ");
                        return 0;
                }
index 2f56b879147bd0e01abd8dcf13b04e39e3fde9b6..cded401e66b3ce471db72ad87af8dfb15e070140 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -2712,27 +2712,28 @@ handle_stopped_tcbs(struct tcb *tcp)
                /* we handled the STATUS, we are permitted to interrupt now. */
                if (interrupted)
                        return 0;
-               if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
-                       /* ptrace() failed in trace_syscall() with ESRCH.
-                        * Likely a result of process disappearing mid-flight.
-                        * Observed case: exit_group() terminating
-                        * all processes in thread group. In this case, threads
-                        * "disappear" in an unpredictable moment without any
-                        * notification to strace via wait().
+               if (trace_syscall(tcp) < 0) {
+                       /* trace_syscall printed incompletely decoded syscall,
+                        * add error indicator.
+                        * NB: modulo bugs, errno must be nonzero, do not add
+                        * "if (err != 0)", this will hide bugs.
                         */
+                       int err = tcp->ptrace_errno;
+                       tcp->ptrace_errno = 0;
+                       if (err == ESRCH)
+                               tprintf(" <unavailable>");
+                       else
+                               tprintf(" <ptrace error %d (%s)>", err, strerror(err));
+                       printtrailer();
+                       if (err == ESRCH)
+                               /* Want to get death report anyway. */
+                               goto tracing;
+                       /* Strange error, we dare not continue. */
                        if (tcp->flags & TCB_ATTACHED) {
-                               if (tcp_last) {
-                                       /* Do we have dangling line "syscall(param, param"?
-                                        * Finish the line then. We cannot
-                                        */
-                                       tcp_last->flags |= TCB_REPRINT;
-                                       tprintf(" <unfinished ...>");
-                                       printtrailer();
-                               }
                                detach(tcp, 0);
                        } else {
-                               ptrace(PTRACE_KILL,
-                                       tcp->pid, (char *) 1, SIGTERM);
+                               ptrace(PTRACE_KILL, tcp->pid, (char *) 1, SIGTERM);
+                               /* [why SIGTERM? why not also kill(SIGKILL)?] */
                                droptcb(tcp);
                        }
                        continue;
@@ -2838,13 +2839,25 @@ void
 printleader(struct tcb *tcp)
 {
        if (tcp_last) {
-               if (tcp_last->ptrace_errno) {
+               int err = tcp_last->ptrace_errno;
+               if (err) {
                        tcp_last->ptrace_errno = 0;
                        if (tcp_last->flags & TCB_INSYSCALL) {
-                               tprintf(" <unavailable ...>\n");
+                               if (err == ESRCH)
+                                       tprintf(" <unavailable ...>\n");
+                               else
+                                       tprintf(" <ptrace error %d (%s) ...>\n", err, strerror(err));
                                tcp_last->flags |= TCB_REPRINT;
                        } else {
-                               tprintf("= ? <unavailable>\n");
+                               /* Not sure this branch can ever be reached.
+                                * Oh well. Using subtly different format
+                                * (without "?" after "=") to make it
+                                * noticeable (grep for '= <' in straces).
+                                */
+                               if (err == ESRCH)
+                                       tprintf("= <unavailable>\n");
+                               else
+                                       tprintf("= <ptrace error %d (%s)>\n", err, strerror(err));
                        }
                } else if (!outfname || followfork < 2 || tcp_last == tcp) {
                        tprintf(" <unfinished ...>\n");
index 99b851616e8a77ab7d800b8aff05c0437c725fb2..9722519fcaae00a170011405fc00c2a4156ad101 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -1103,7 +1103,7 @@ get_scno(struct tcb *tcp)
 #elif defined (LINUX_MIPSN32)
        unsigned long long regs[38];
 
-       if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) &regs) < 0)
+       if (do_ptrace(PTRACE_GETREGS, tcp, NULL, (long) &regs) < 0)
                return -1;
        a3 = regs[REG_A3];
        r2 = regs[REG_V0];
@@ -1351,11 +1351,11 @@ struct tcb *tcp;
        return scno;
 }
 
-/* Called in trace_syscall() at each syscall entry and exit.
+/* Called in trace_syscall at each syscall entry and exit.
  * Returns:
- * 0: "ignore this syscall", bail out of trace_syscall() silently.
- * 1: ok, continue in trace_syscall().
- * other: error, trace_syscall() should print error indicator
+ * 0: "ignore this syscall", bail out of trace_syscall silently.
+ * 1: ok, continue in trace_syscall.
+ * other: error, trace_syscall should print error indicator
  *    ("????" etc) and bail out.
  */
 static int
@@ -1937,10 +1937,11 @@ force_result(tcp, error, rval)
 #endif /* S390 || S390X */
 #endif /* LINUX */
 #ifdef SUNOS4
-       if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
-                  error << 24) < 0 ||
-           ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
+       if (do_ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error), error << 24) < 0
+        || do_ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0
+       ) {
                return -1;
+       }
 #endif /* SUNOS4 */
 #ifdef SVR4
        /* XXX no clue */
@@ -2071,10 +2072,10 @@ struct tcb *tcp;
                else
                        nargs = tcp->u_nargs = MAX_ARGS;
 
-               if (ptrace (PTRACE_GETREGS, pid, NULL, (long) &regs) < 0)
+               if (do_ptrace(PTRACE_GETREGS, tcp, NULL, (long) &regs) < 0)
                        return -1;
 
-               for(i = 0; i < nargs; i++) {
+               for (i = 0; i < nargs; i++) {
                        tcp->u_arg[i] = regs[REG_A0 + i];
 # if defined (LINUX_MIPSN32)
                        tcp->ext_arg[i] = regs[REG_A0 + i];
@@ -2090,17 +2091,17 @@ struct tcb *tcp;
                        nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
                else
                        nargs = tcp->u_nargs = MAX_ARGS;
-               if(nargs > 4) {
-                       if(upeek(tcp, REG_SP, &sp) < 0)
+               if (nargs > 4) {
+                       if (upeek(tcp, REG_SP, &sp) < 0)
                                return -1;
-                       for(i = 0; i < 4; i++) {
+                       for (i = 0; i < 4; i++) {
                                if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i])<0)
                                        return -1;
                        }
                        umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
                               (char *)(tcp->u_arg + 4));
                } else {
-                       for(i = 0; i < nargs; i++) {
+                       for (i = 0; i < nargs; i++) {
                                if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
                                        return -1;
                        }
@@ -2349,7 +2350,12 @@ trace_syscall(struct tcb *tcp)
                if (dtime)
                        gettimeofday(&tv, NULL);
 
-               /* BTW, why we don't just memorize syscall no. on entry
+               /* In code below,
+                * res = 1: no error, continue
+                * res = 0: return 0 at once (not an error)
+                * any other value: error, complain and return the value
+                *
+                * BTW, why we don't just memorize syscall no. on entry
                 * in tcp->something?
                 */
                scno_good = res = get_scno(tcp);
@@ -2374,14 +2380,15 @@ trace_syscall(struct tcb *tcp)
 
                if (tcp->flags & TCB_REPRINT) {
                        printleader(tcp);
-                       tprintf("<... ");
-                       if (scno_good != 1)
-                               tprintf("????");
-                       else if (tcp->scno >= nsyscalls || tcp->scno < 0)
-                               tprintf("syscall_%lu", tcp->scno);
-                       else
-                               tprintf("%s", sysent[tcp->scno].sys_name);
-                       tprintf(" resumed> ");
+                       if (scno_good != 1) {
+                               tprintf("<... syscall_?? resumed> ");
+                       } else {
+                               if (tcp->scno >= nsyscalls || tcp->scno < 0)
+                                       tprintf("<... syscall_%lu resumed> ", tcp->scno);
+                               else
+                                       tprintf("<... %s resumed> ", sysent[tcp->scno].sys_name);
+                       }
+                       /* [do we need to clear TCB_REPRINT?...] */
                }
 
                if (cflag)
@@ -2390,8 +2397,8 @@ trace_syscall(struct tcb *tcp)
                if (res != 1) {
                        tprintf(") ");
                        tabto(acolumn);
-                       tprintf("= ? <unavailable>");
-                       printtrailer();
+                       tprintf("= ?");
+                       /* line will be finished by error handling code */
                        tcp->flags &= ~TCB_INSYSCALL;
                        return res;
                }
@@ -2514,18 +2521,15 @@ trace_syscall(struct tcb *tcp)
 
        if (res != 1) {
                printleader(tcp);
-               tcp->flags &= ~TCB_REPRINT;
+               tcp->flags &= ~TCB_REPRINT; /* why? */
                tcp_last = tcp;
                if (scno_good != 1)
-                       tprintf("????" /* anti-trigraph gap */ "(");
+                       tprintf("syscall_??" /* anti-trigraph gap */ "(");
                else if (tcp->scno >= nsyscalls || tcp->scno < 0)
                        tprintf("syscall_%lu(", tcp->scno);
                else
                        tprintf("%s(", sysent[tcp->scno].sys_name);
-               /*
-                * " <unavailable>" will be added later by the code which
-                * detects ptrace errors.
-                */
+               /* Line will be finished by error handling code. */
                tcp->flags |= TCB_INSYSCALL;
                return res;
        }
@@ -2679,7 +2683,7 @@ struct tcb *tcp;
 #ifdef LINUX
 #if defined (SPARC) || defined (SPARC64)
        struct regs regs;
-       if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
+       if (do_ptrace(PTRACE_GETREGS, tcp, (char *)&regs, 0) < 0)
                return -1;
        val = regs.r_o1;
 #elif defined(SH)
diff --git a/util.c b/util.c
index ca38f1d146576d7febc071ab6d58632dddcf9c13..4a17d40e011c1a46b80f4172d0c2ec51df69ffc6 100644 (file)
--- a/util.c
+++ b/util.c
@@ -241,30 +241,103 @@ xlookup(const struct xlat *xlat, int val)
 }
 
 /*
- * Generic ptrace wrapper which tracks ESRCH errors
- * by setting tcp->ptrace_errno to ESRCH.
+ * Generic ptrace wrapper which tracks ptrace errors
+ * by setting tcp->ptrace_errno.
  *
  * We assume that ESRCH indicates likely process death (SIGKILL?),
  * modulo bugs where process somehow ended up not stopped.
  * Unfortunately kernel uses ESRCH for that case too. Oh well.
- *
- * Currently used by upeek() only.
- * TODO: use this in all other ptrace() calls while decoding.
  */
+static const char *
+str_PTRACE_xxx(int request)
+{
+       const char *s;
+       static char msg[sizeof(int) * 3 + sizeof("PTRACE_<%d>")];
+
+       s = xlookup(ptrace_cmds, request);
+       if (s)
+               return s;
+       sprintf(msg, "PTRACE_<%d>", request);
+       return msg;
+}
+
 long
-do_ptrace(int request, struct tcb *tcp, void *addr, void *data)
+do_ptrace(int request, struct tcb *tcp, void *addr, long data)
 {
+       int err;
        long l;
 
        errno = 0;
        l = ptrace(request, tcp->pid, addr, data);
-       /* Non-ESRCH errors might be our invalid reg/mem accesses,
-        * we do not record them. */
-       if (errno == ESRCH)
-               tcp->ptrace_errno = ESRCH;
+       err = errno;
+       if (err) {
+               tcp->ptrace_errno = err;
+               if (err != ESRCH) {
+                       fprintf(stderr, "strace: ptrace(%s,%u,%p,%lu): %s\n",
+                               str_PTRACE_xxx(request),
+                               (int) tcp->pid, addr, data, strerror(err));
+                       errno = err; /* fprintf can clobber it, restore */
+               }
+               return -1;
+       }
+       return l;
+}
+
+static long
+do_ptrace_peekdata(struct tcb *tcp, void *addr, int started)
+{
+       int err;
+       long l;
+
+       errno = 0;
+       l = ptrace(PTRACE_PEEKDATA, tcp->pid, addr, 0);
+       err = errno;
+       if (err) {
+               if (started && (err == EPERM || err == EIO)) {
+                       /* Ran into 'end of memory' - not an error.
+                        * NB: errno is nonzero, caller uses this to detect
+                        * "end of string" condition.
+                        */
+                       return 0;
+               }
+               /* If error happens at first call, we have a bogus address. */
+               if (addr != NULL && err != EIO) {
+                       if (err != ESRCH) {
+                               fprintf(stderr, "strace: ptrace(PTRACE_PEEKDATA,%u,%p,0): %s\n",
+                                       (int) tcp->pid, addr, strerror(err));
+                               errno = err; /* fprintf can clobber it, restore */
+                       }
+                       tcp->ptrace_errno = err;
+                       return -1;
+               }
+       }
        return l;
 }
 
+#ifdef SUNOS4
+static long
+do_ptrace5(int request, struct tcb *tcp, void *addr, long data, char *data2)
+{
+       int err;
+       long l;
+
+       errno = 0;
+       l = ptrace(request, tcp->pid, addr, data, data2);
+       err = errno;
+       if (err) {
+               tcp->ptrace_errno = err;
+               if (err != ESRCH) {
+                       fprintf(stderr, "strace: ptrace(%s,%u,%p,%lu,%p): %s\n",
+                               str_PTRACE_xxx(request),
+                               (int) tcp->pid, addr, data, data2, strerror(err));
+                       errno = err; /* fprintf can clobber it, restore */
+               }
+               return -1;
+       }
+       return l;
+}
+#endif
+
 /*
  * Used when we want to unblock stopped traced process.
  * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
@@ -273,25 +346,21 @@ do_ptrace(int request, struct tcb *tcp, void *addr, void *data)
  * Otherwise prints error message and returns -1.
  */
 int
-ptrace_restart(int op, struct tcb *tcp, int sig)
+ptrace_restart(int request, struct tcb *tcp, int sig)
 {
        int err;
-       const char *msg;
 
        errno = 0;
-       ptrace(op, tcp->pid, (void *) 1, (void *) (long) sig);
+       ptrace(request, tcp->pid, (void *) 1, (long) sig);
        err = errno;
        if (!err || err == ESRCH)
                return 0;
 
        tcp->ptrace_errno = err;
-       msg = "SYSCALL";
-       if (op == PTRACE_CONT)
-               msg = "CONT";
-       if (op == PTRACE_DETACH)
-               msg = "DETACH";
-       fprintf(stderr, "strace: ptrace(PTRACE_%s,1,%d): %s\n",
-                       msg, sig, strerror(err));
+       fprintf(stderr, "strace: ptrace(%s,%u,1,%d): %s\n",
+                       str_PTRACE_xxx(request),
+                       (int)tcp->pid, sig, strerror(err));
+       errno = err; /* fprintf can clobber it, restore */
        return -1;
 }
 
@@ -788,7 +857,6 @@ int
 umoven(struct tcb *tcp, long addr, int len, char *laddr)
 {
 #ifdef LINUX
-       int pid = tcp->pid;
        int n, m;
        int started = 0;
        union {
@@ -800,34 +868,17 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr)
                /* addr not a multiple of sizeof(long) */
                n = addr - (addr & -sizeof(long)); /* residue */
                addr &= -sizeof(long); /* residue */
-               errno = 0;
-               u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
-               if (errno) {
-                       if (started && (errno==EPERM || errno==EIO)) {
-                               /* Ran into 'end of memory' - stupid "printpath" */
-                               return 0;
-                       }
-                       /* But if not started, we had a bogus address. */
-                       if (addr != 0 && errno != EIO && errno != ESRCH)
-                               perror("ptrace: umoven");
-                       return -1;
-               }
+               u.val = do_ptrace_peekdata(tcp, (char *) addr, started);
+               if (errno)
+                       return u.val; /* 0 or -1 */
                started = 1;
                memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
                addr += sizeof(long), laddr += m, len -= m;
        }
        while (len) {
-               errno = 0;
-               u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
-               if (errno) {
-                       if (started && (errno==EPERM || errno==EIO)) {
-                               /* Ran into 'end of memory' - stupid "printpath" */
-                               return 0;
-                       }
-                       if (addr != 0 && errno != EIO && errno != ESRCH)
-                               perror("ptrace: umoven");
-                       return -1;
-               }
+               u.val = do_ptrace_peekdata(tcp, (char *) addr, started);
+               if (errno)
+                       return u.val; /* 0 or -1 */
                started = 1;
                memcpy(laddr, u.x, m = MIN(sizeof(long), len));
                addr += sizeof(long), laddr += m, len -= m;
@@ -847,24 +898,16 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr)
                /* addr not a multiple of sizeof(long) */
                n = addr - (addr & -sizeof(long)); /* residue */
                addr &= -sizeof(long); /* residue */
-               errno = 0;
-               u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
-               if (errno) {
-                       if (errno != ESRCH)
-                               perror("umoven");
+               u.val = do_ptrace(PTRACE_PEEKDATA, tcp, (char *) addr, 0);
+               if (errno)
                        return -1;
-               }
                memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
                addr += sizeof(long), laddr += m, len -= m;
        }
        while (len) {
-               errno = 0;
-               u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
-               if (errno) {
-                       if (errno != ESRCH)
-                               perror("umoven");
+               u.val = do_ptrace(PTRACE_PEEKDATA, tcp, (char *) addr, 0);
+               if (errno)
                        return -1;
-               }
                memcpy(laddr, u.x, m = MIN(sizeof(long), len));
                addr += sizeof(long), laddr += m, len -= m;
        }
@@ -874,12 +917,7 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr)
        while (len) {
                n = MIN(len, PAGSIZ);
                n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
-               if (ptrace(PTRACE_READDATA, pid,
-                          (char *) addr, len, laddr) < 0) {
-                       if (errno != ESRCH) {
-                               perror("umoven: ptrace(PTRACE_READDATA, ...)");
-                               abort();
-                       }
+               if (do_ptrace5(PTRACE_READDATA, tcp, (char *) addr, len, laddr) < 0) {
                        return -1;
                }
                len -= n;
@@ -941,7 +979,6 @@ umovestr(struct tcb *tcp, long addr, int len, char *laddr)
        }
 #else /* !USE_PROCFS */
        int started = 0;
-       int pid = tcp->pid;
        int i, n, m;
        union {
                long val;
@@ -952,17 +989,9 @@ umovestr(struct tcb *tcp, long addr, int len, char *laddr)
                /* addr not a multiple of sizeof(long) */
                n = addr - (addr & -sizeof(long)); /* residue */
                addr &= -sizeof(long); /* residue */
-               errno = 0;
-               u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
-               if (errno) {
-                       if (started && (errno==EPERM || errno==EIO)) {
-                               /* Ran into 'end of memory' - stupid "printpath" */
-                               return 0;
-                       }
-                       if (addr != 0 && errno != EIO && errno != ESRCH)
-                               perror("umovestr");
-                       return -1;
-               }
+               u.val = do_ptrace_peekdata(tcp, (char *)addr, started);
+               if (errno)
+                       return u.val; /* 0 or -1 */
                started = 1;
                memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
                while (n & (sizeof(long) - 1))
@@ -971,17 +1000,9 @@ umovestr(struct tcb *tcp, long addr, int len, char *laddr)
                addr += sizeof(long), laddr += m, len -= m;
        }
        while (len) {
-               errno = 0;
-               u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
-               if (errno) {
-                       if (started && (errno==EPERM || errno==EIO)) {
-                               /* Ran into 'end of memory' - stupid "printpath" */
-                               return 0;
-                       }
-                       if (addr != 0 && errno != EIO && errno != ESRCH)
-                               perror("umovestr");
-                       return -1;
-               }
+               u.val = do_ptrace_peekdata(tcp, (char *)addr, started);
+               if (errno)
+                       return u.val; /* 0 or -1 */
                started = 1;
                memcpy(laddr, u.x, m = MIN(sizeof(long), len));
                for (i = 0; i < sizeof(long); i++)
@@ -1004,12 +1025,7 @@ umovestr(struct tcb *tcp, long addr, int len, char *laddr)
 #ifdef SUNOS4
 
 static int
-uload(cmd, pid, addr, len, laddr)
-int cmd;
-int pid;
-long addr;
-int len;
-char *laddr;
+uload(int cmd, struct tcb *tcp, long addr, int len, char *laddr)
 {
 # if 0
        int n;
@@ -1017,8 +1033,7 @@ char *laddr;
        while (len) {
                n = MIN(len, PAGSIZ);
                n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
-               if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
-                       perror("uload: ptrace(PTRACE_WRITE, ...)");
+               if (do_ptrace5(cmd, tcp, (char *)addr, n, laddr) < 0) {
                        return -1;
                }
                len -= n;
@@ -1045,50 +1060,39 @@ char *laddr;
                /* addr not a multiple of sizeof(long) */
                n = addr - (addr & -sizeof(long)); /* residue */
                addr &= -sizeof(long);
-               errno = 0;
-               u.val = ptrace(peek, pid, (char *) addr, 0);
-               if (errno) {
-                       perror("uload: POKE");
+               u.val = do_ptrace(peek, tcp, (char *) addr, 0);
+               if (errno)
                        return -1;
-               }
-               memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
-               if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
-                       perror("uload: POKE");
+               m = MIN(sizeof(long) - n;
+               memcpy(&u.x[n], laddr, m, len));
+               if (do_ptrace(poke, tcp, (char *)addr, u.val) < 0) {
                        return -1;
                }
-               addr += sizeof(long), laddr += m, len -= m;
+               addr += sizeof(long);
+               laddr += m;
+               len -= m;
        }
+       errno = 0;
        while (len) {
                if (len < sizeof(long))
-                       u.val = ptrace(peek, pid, (char *) addr, 0);
-               memcpy(u.x, laddr, m = MIN(sizeof(long), len));
-               if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
-                       perror("uload: POKE");
+                       u.val = do_ptrace(peek, tcp, (char *) addr, 0);
+               m = MIN(sizeof(long), len);
+               memcpy(u.x, laddr, m);
+               if (errno || do_ptrace(poke, tcp, (char *) addr, u.val) < 0) {
                        return -1;
                }
-               addr += sizeof(long), laddr += m, len -= m;
+               addr += sizeof(long);
+               laddr += m;
+               len -= m;
        }
 # endif
        return 0;
 }
 
-int
-tload(pid, addr, len, laddr)
-int pid;
-int addr, len;
-char *laddr;
-{
-       return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
-}
-
-int
-dload(pid, addr, len, laddr)
-int pid;
-int addr;
-int len;
-char *laddr;
+static int
+tload(struct tcb *tcp, int addr, int len, char *laddr)
 {
-       return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
+       return uload(PTRACE_WRITETEXT, tcp, addr, len, laddr);
 }
 
 #endif /* SUNOS4 */
@@ -1096,10 +1100,7 @@ char *laddr;
 #ifndef USE_PROCFS
 
 int
-upeek(tcp, off, res)
-struct tcb *tcp;
-long off;
-long *res;
+upeek(struct tcb *tcp, long off, long *res)
 {
        long val;
 
@@ -1126,16 +1127,9 @@ long *res;
                        off += 1024;
        }
 # endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
-       errno = 0;
        val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0);
-       if (val == -1 && errno) {
-               if (errno != ESRCH) {
-                       char buf[60];
-                       sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off);
-                       perror(buf);
-               }
+       if (errno)
                return -1;
-       }
        *res = val;
        return 0;
 }
@@ -1179,17 +1173,17 @@ struct tcb *tcp;
                return -1;
 # elif defined(SPARC) || defined(SPARC64)
        struct regs regs;
-       if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
+       if (do_ptrace(PTRACE_GETREGS, tcp, (char *) &regs, 0) < 0)
                return -1;
        pc = regs.r_pc;
 # elif defined(S390) || defined(S390X)
-       if(upeek(tcp,PT_PSWADDR,&pc) < 0)
+       if (upeek(tcp, PT_PSWADDR, &pc) < 0)
                return -1;
 # elif defined(HPPA)
-       if(upeek(tcp,PT_IAOQ0,&pc) < 0)
+       if (upeek(tcp, PT_IAOQ0, &pc) < 0)
                return -1;
 # elif defined(SH)
-       if (upeek(tcp, 4*REG_PC ,&pc) < 0)
+       if (upeek(tcp, 4*REG_PC&pc) < 0)
                return -1;
 # elif defined(SH64)
        if (upeek(tcp, REG_PC ,&pc) < 0)
@@ -1205,10 +1199,8 @@ struct tcb *tcp;
         */
        struct regs regs;
 
-       if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
-               perror("getpc: ptrace(PTRACE_GETREGS, ...)");
+       if (do_ptrace(PTRACE_GETREGS, tcp, (char *) &regs, 0) < 0)
                return -1;
-       }
        return regs.r_pc;
 #endif /* SUNOS4 */
 
@@ -1245,7 +1237,7 @@ struct tcb *tcp;
 
 # elif defined(S390) || defined(S390X)
        long psw;
-       if(upeek(tcp,PT_PSWADDR,&psw) < 0) {
+       if (upeek(tcp, PT_PSWADDR, &psw) < 0) {
                PRINTBADPC;
                return;
        }
@@ -1297,7 +1289,7 @@ struct tcb *tcp;
        tprintf("[%08lx] ", pc);
 # elif defined(SPARC) || defined(SPARC64)
        struct regs regs;
-       if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
+       if (do_ptrace(PTRACE_GETREGS, tcp, (char *) &regs, 0) < 0) {
                PRINTBADPC;
                return;
        }
@@ -1305,7 +1297,7 @@ struct tcb *tcp;
 # elif defined(HPPA)
        long pc;
 
-       if(upeek(tcp,PT_IAOQ0,&pc) < 0) {
+       if (upeek(tcp, PT_IAOQ0, &pc) < 0) {
                tprintf ("[????????] ");
                return;
        }
@@ -1356,8 +1348,7 @@ struct tcb *tcp;
 #ifdef SUNOS4
        struct regs regs;
 
-       if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
-               perror("printcall: ptrace(PTRACE_GETREGS, ...)");
+       if (do_ptrace(PTRACE_GETREGS, tcp, (char *) &regs, 0) < 0) {
                PRINTBADPC;
                return;
        }
@@ -1478,9 +1469,9 @@ set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
                req = PTRACE_POKEUSER;
        } else
                ap = ia64_rse_skip_regs(*state, 0);
-       errno = 0;
-       ptrace(req, tcp->pid, ap, val);
-       return errno ? -1 : 0;
+       if (do_ptrace(req, tcp, ap, val) < 0)
+               return -1;
+       return 0;
 }
 
 static int
@@ -1494,9 +1485,9 @@ set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
                req = PTRACE_POKEUSER;
        } else
                ap = ia64_rse_skip_regs(*state, 1);
-       errno = 0;
-       ptrace(req, tcp->pid, ap, val);
-       return errno ? -1 : 0;
+       if (do_ptrace(req, tcp, ap, val) < 0)
+               return -1;
+       return 0;
 }
 
 /* ia64 does not return the input arguments from functions (and syscalls)
@@ -1510,9 +1501,9 @@ set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
 typedef struct regs arg_setup_state;
 
 #   define arg_setup(tcp, state) \
-    (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
+    (do_ptrace(PTRACE_GETREGS, tcp, (char *) (state), 0))
 #   define arg_finish_change(tcp, state) \
-    (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
+    (do_ptrace(PTRACE_SETREGS, tcp, (char *) (state), 0))
 
 #   define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
 #   define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
@@ -1572,15 +1563,15 @@ typedef int arg_setup_state;
     (upeek ((tcp), arg1_offset, (valp)))
 
 static int
-set_arg0 (struct tcb *tcp, void *cookie, long val)
+set_arg0(struct tcb *tcp, void *cookie, long val)
 {
-       return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
+       return do_ptrace(PTRACE_POKEUSER, tcp, (char*)arg0_offset, val);
 }
 
 static int
-set_arg1 (struct tcb *tcp, void *cookie, long val)
+set_arg1(struct tcb *tcp, void *cookie, long val)
 {
-       return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
+       return do_ptrace(PTRACE_POKEUSER, tcp, (char*)arg1_offset, val);
 }
 
 #  endif /* architectures */
@@ -1710,17 +1701,13 @@ struct tcb *tcp;
                fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
                return -1;
        }
-       if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
-               perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
+       if (do_ptrace(PTRACE_GETREGS, tcp, (char *)&regs, 0) < 0) {
                return -1;
        }
        tcp->baddr = regs.r_o7 + 8;
-       errno = 0;
-       tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
-       if(errno) {
-               perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
+       tcp->inst[0] = do_ptrace(PTRACE_PEEKTEXT, tcp, (char *)tcp->baddr, 0);
+       if (errno)
                return -1;
-       }
 
        /*
         * XXX - BRUTAL MODE ON
@@ -1738,11 +1725,8 @@ struct tcb *tcp;
        inst <<= 32;
        inst |= (tcp->inst[0] & 0xffffffffUL);
 #    endif
-       ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst);
-       if(errno) {
-               perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
+       if (do_ptrace(PTRACE_POKETEXT, tcp, (char *) tcp->baddr, inst) < 0)
                return -1;
-       }
        tcp->flags |= TCB_BPTSET;
 
 #   else /* !SPARC && !SPARC64 */
@@ -1759,17 +1743,11 @@ struct tcb *tcp;
                if (debug)
                        fprintf(stderr, "[%d] setting bpt at %lx\n",
                                tcp->pid, tcp->baddr);
-               tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
-                                     (char *) tcp->baddr, 0);
-               if (errno) {
-                       perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
+               tcp->inst[0] = do_ptrace(PTRACE_PEEKTEXT, tcp, (char *) tcp->baddr, 0);
+               if (errno)
                        return -1;
-               }
-               ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
-               if (errno) {
-                       perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
+               if (do_ptrace(PTRACE_POKETEXT, tcp, (char *) tcp->baddr, LOOP) < 0)
                        return -1;
-               }
                tcp->flags |= TCB_BPTSET;
        } else {
                /*
@@ -1795,21 +1773,15 @@ struct tcb *tcp;
                /* store "ri" in low two bits */
                tcp->baddr = addr | ((ipsr >> 41) & 0x3);
 
-               errno = 0;
-               tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
-                                     0);
-               tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
-                                     0);
-               if (errno) {
-                       perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
+               tcp->inst[0] = do_ptrace(PTRACE_PEEKTEXT, tcp, (char *) addr + 0, 0);
+               if (!errno)
+                       tcp->inst[1] = do_ptrace(PTRACE_PEEKTEXT, tcp, (char *) addr + 8, 0);
+               if (errno)
                        return -1;
-               }
 
-               errno = 0;
-               ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
-               ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
-               if (errno) {
-                       perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
+               if (do_ptrace(PTRACE_POKETEXT, tcp, (char *) addr + 0, LOOP0) < 0
+                || do_ptrace(PTRACE_POKETEXT, tcp, (char *) addr + 8, LOOP1) < 0
+               ) {
                        return -1;
                }
                tcp->flags |= TCB_BPTSET;
@@ -1881,14 +1853,10 @@ struct tcb *tcp;
 #     endif
        if (debug)
                fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
-       tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
-       if (errno) {
-               perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
+       tcp->inst[0] = do_ptrace(PTRACE_PEEKTEXT, tcp, (char *) tcp->baddr, 0);
+       if (errno)
                return -1;
-       }
-       ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
-       if (errno) {
-               perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
+       if (do_ptrace(PTRACE_POKETEXT, tcp, (char *) tcp->baddr, LOOP) < 0) {
                return -1;
        }
        tcp->flags |= TCB_BPTSET;
@@ -1915,14 +1883,12 @@ struct tcb *tcp;
                fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
                return -1;
        }
-       if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
-               perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
+       if (do_ptrace(PTRACE_GETREGS, tcp, (char *)&regs, 0) < 0) {
                return -1;
        }
        tcp->baddr = regs.r_o7 + 8;
-       if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
-                               sizeof tcp->inst, (char *)tcp->inst) < 0) {
-               perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
+       if (do_ptrace5(PTRACE_READTEXT, tcp, (char *)tcp->baddr,
+                               sizeof tcp->inst, (char *)tcp->inst, "READTEXT") < 0) {
                return -1;
        }
 
@@ -1936,9 +1902,8 @@ struct tcb *tcp;
         * generated by out PTRACE_ATTACH.
         * Of cause, if we evaporate ourselves in the middle of all this...
         */
-       if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
+       if (do_ptrace5(PTRACE_WRITETEXT, tcp, (char *) tcp->baddr,
                        sizeof loopdeloop, (char *) loopdeloop) < 0) {
-               perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
                return -1;
        }
        tcp->flags |= TCB_BPTSET;
@@ -1976,10 +1941,7 @@ struct tcb *tcp;
                fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
                return -1;
        }
-       errno = 0;
-       ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
-       if(errno) {
-               perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
+       if (do_ptrace(PTRACE_POKETEXT, tcp, (char *) tcp->baddr, tcp->inst[0]) < 0) {
                return -1;
        }
        tcp->flags &= ~TCB_BPTSET;
@@ -1993,10 +1955,7 @@ struct tcb *tcp;
                        fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
                        return -1;
                }
-               errno = 0;
-               ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
-               if (errno) {
-                       perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
+               if (do_ptrace(PTRACE_POKETEXT, tcp, (char *) tcp->baddr, tcp->inst[0]) < 0) {
                        return -1;
                }
                tcp->flags &= ~TCB_BPTSET;
@@ -2023,20 +1982,15 @@ struct tcb *tcp;
                        return -1;
 
                /* restore original bundle: */
-               errno = 0;
-               ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
-               ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
-               if (errno) {
-                       perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
+               if (do_ptrace(PTRACE_POKETEXT, tcp, (char *) addr + 0, tcp->inst[0]) < 0
+                || do_ptrace(PTRACE_POKETEXT, tcp, (char *) addr + 8, tcp->inst[1]) < 0
+               ) {
                        return -1;
                }
 
                /* restore original "ri" in ipsr: */
                ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
-               errno = 0;
-               ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
-               if (errno) {
-                       perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
+               if (do_ptrace(PTRACE_POKEUSER, tcp, (char *) PT_CR_IPSR, ipsr) < 0) {
                        return -1;
                }
 
@@ -2058,10 +2012,7 @@ struct tcb *tcp;
                fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
                return -1;
        }
-       errno = 0;
-       ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
-       if (errno) {
-               perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
+       if (do_ptrace(PTRACE_POKETEXT, tcp, (char *) tcp->baddr, tcp->inst[0]) < 0) {
                return -1;
        }
        tcp->flags &= ~TCB_BPTSET;
@@ -2134,8 +2085,11 @@ struct tcb *tcp;
         * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
         * has no significant effect.
         */
-       ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
-       ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
+       if (do_ptrace(PTRACE_POKEUSER, tcp, (void *)PT_IAOQ0, iaoq) < 0
+        || do_ptrace(PTRACE_POKEUSER, tcp, (void *)PT_IAOQ1, iaoq) < 0
+       ) {
+               return -1;
+       }
 #    elif defined(SH)
        if (upeek(tcp, 4*REG_PC, &pc) < 0)
                return -1;
@@ -2162,9 +2116,8 @@ struct tcb *tcp;
                fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
                return -1;
        }
-       if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
+       if (do_ptrace5(PTRACE_WRITETEXT, tcp, (char *) tcp->baddr,
                                sizeof tcp->inst, (char *) tcp->inst) < 0) {
-               perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
                return -1;
        }
        tcp->flags &= ~TCB_BPTSET;
@@ -2174,12 +2127,10 @@ struct tcb *tcp;
         * Since we don't have a single instruction breakpoint, we may have
         * to adjust the program counter after removing our `breakpoint'.
         */
-       if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
-               perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
+       if (do_ptrace(PTRACE_GETREGS, tcp, (char *)&regs, 0) < 0) {
                return -1;
        }
-       if ((regs.r_pc < tcp->baddr) ||
-                               (regs.r_pc > tcp->baddr + 4)) {
+       if ((regs.r_pc < tcp->baddr) || (regs.r_pc > tcp->baddr + 4)) {
                /* The breakpoint has not been reached yet */
                if (debug)
                        fprintf(stderr,
@@ -2193,8 +2144,7 @@ struct tcb *tcp;
                                regs.r_pc, tcp->baddr);
 
        regs.r_pc = tcp->baddr;
-       if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
-               perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
+       if (do_ptrace(PTRACE_SETREGS, tcp, (char *)&regs, 0) < 0) {
                return -1;
        }
 #    endif /* LOOPA */
@@ -2265,7 +2215,7 @@ struct tcb *tcp;
                fprintf(stderr, "out of memory\n");
                return -1;
        }
-       if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
+       if (umoven(tcp, (int)ld.ld_symbols + (int)N_TXTADDR(hdr),
                                        (int)ld.ld_symb_size, strtab) < 0)
                goto err;
 
@@ -2290,7 +2240,7 @@ struct tcb *tcp;
                 * Write entire symbol table back to avoid
                 * memory alignment bugs in ptrace
                 */
-               if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
+               if (tload(tcp, (int)ld.ld_symbols + (int)N_TXTADDR(hdr),
                                        (int)ld.ld_symb_size, strtab) < 0)
                        goto err;