summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2013-02-26 12:24:25 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2013-02-26 12:24:25 +0100
commit1d58fe9b3b925735bde72cac96a042b3cef03037 (patch)
tree229a7db2039344d07f0337c405de5b0e62c25fb0 /util.c
parent05f325199a6cf36c92560d5a08b56652502705c2 (diff)
downloadstrace-1d58fe9b3b925735bde72cac96a042b3cef03037.tar.gz
strace-1d58fe9b3b925735bde72cac96a042b3cef03037.tar.bz2
strace-1d58fe9b3b925735bde72cac96a042b3cef03037.tar.xz
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 <vda.linux@googlemail.com>
Diffstat (limited to 'util.c')
-rw-r--r--util.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/util.c b/util.c
index 405670e..88798c0 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;