From: Ben Noordhuis Date: Tue, 26 Feb 2013 11:24:25 +0000 (+0100) Subject: Make umoven report success as 0, not >=0, stop returning success on partial reads X-Git-Tag: v4.8~119 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d58fe9b3b925735bde72cac96a042b3cef03037;p=strace Make umoven report success as 0, not >=0, stop returning success on partial reads umoven() uses process_vm_readv() when available but it returns the return value of that syscall, which is the number of bytes copied, while its callers expect it to simply return zero on success. It was causing syscalls that take a user-space argument to print the abbreviated version, e.g.: epoll_ctl(5, EPOLL_CTL_ADD, 10, {...}) Instead of: epoll_ctl(5, EPOLL_CTL_ADD, 10, {EPOLLIN, {u32=10, u64=10}}) * util.c (umoven): Make umove[n] report success as 0, not >=0, stop returning "success" on partial reads. Signed-off-by: Denys Vlasenko --- diff --git a/util.c b/util.c index 405670e6..88798c0a 100644 --- a/util.c +++ b/util.c @@ -777,7 +777,7 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr) { int pid = tcp->pid; int n, m; - int started; + //int started; union { long val; char x[sizeof(long)]; @@ -800,6 +800,8 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr) remote, 1, /*flags:*/ 0 ); + if (r == len) + return 0; if (r < 0) { if (errno == ENOSYS) process_vm_readv_not_supported = 1; @@ -807,13 +809,12 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr) /* EINVAL or ESRCH could be seen if process is gone, * all the rest is strange and should be reported. */ perror_msg("%s", "process_vm_readv"); - goto vm_readv_didnt_work; + } else { + perror_msg("process_vm_readv: short read (%d < %d)", r, len); } - return r; } - vm_readv_didnt_work: - started = 0; + //started = 0; if (addr & (sizeof(long) - 1)) { /* addr not a multiple of sizeof(long) */ n = addr - (addr & -sizeof(long)); /* residue */ @@ -826,7 +827,7 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr) perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr); return -1; } - started = 1; + //started = 1; m = MIN(sizeof(long) - n, len); memcpy(laddr, &u.x[n], m); addr += sizeof(long), laddr += m, len -= m; @@ -835,15 +836,19 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr) errno = 0; u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); if (errno) { +#if 0 +//FIXME: wrong. printpath doesn't use this routine. Callers expect full copies. +//Ok to remove? if (started && (errno==EPERM || errno==EIO)) { /* Ran into 'end of memory' - stupid "printpath" */ return 0; } +#endif if (addr != 0 && errno != EIO && errno != ESRCH) perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr); return -1; } - started = 1; + //started = 1; m = MIN(sizeof(long), len); memcpy(laddr, u.x, m); addr += sizeof(long), laddr += m, len -= m;