From: Eugene Syromyatnikov Date: Fri, 14 Oct 2016 23:30:47 +0000 (+0300) Subject: io: use umoven_or_printaddr_ignore_syserror as umove function in tprint_iov_upto X-Git-Tag: v4.15~207 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=030b61c92fd84bfc94181f1e29c75d9c219a3467;p=strace io: use umoven_or_printaddr_ignore_syserror as umove function in tprint_iov_upto This enables printing of iovec arrays even in case of failed syscall (failed syscall doesn't mean that iovec itself is inaccessible and useless). One caveat here is that we should explicitly provide proper IOV_DECODE_* value based on syserror value in case printing is performed on exiting; we can't simply override it to IOV_DECODE_ADDR on exiting when syserror is up, since this may be called by code which tries to print iovec containing local data, which should be perfectly accessible (on the other hand, there are no cases of such behaviour at the moment). Since iovecs themselves are printed even if syscall has failed now, preadv test is updated to reflect this. It is notable, though, that this is the only place where this case is checked. * io.c (tprint_iov_upto): Specify umoven_or_printaddr_ignore_syserror instead of umoven_or_printaddr as umoven_func parameter. (SYS_FUNC(readv), do_preadv): Specify decode_iov parameter value based on syserror(tcp) value. * scsi.c: (print_sg_io_v3_res, print_sg_io_v4_res): Likewise. * tests/preadv.c: Update expected output for the case when preadv with singe-item iovec failed. --- diff --git a/io.c b/io.c index 8a93cb89..fe865a5d 100644 --- a/io.c +++ b/io.c @@ -119,7 +119,7 @@ tprint_iov_upto(struct tcb *tcp, unsigned long len, unsigned long addr, { .decode_iov = decode_iov, .data_size = data_size }; print_array(tcp, addr, len, iov, current_wordsize * 2, - umoven_or_printaddr, print_iovec, &config); + umoven_or_printaddr_ignore_syserror, print_iovec, &config); } void @@ -136,6 +136,7 @@ SYS_FUNC(readv) tprints(", "); } else { tprint_iov_upto(tcp, tcp->u_arg[2], tcp->u_arg[1], + syserror(tcp) ? IOV_DECODE_ADDR : IOV_DECODE_STR, tcp->u_rval); tprintf(", %lu", tcp->u_arg[2]); } @@ -226,8 +227,9 @@ do_preadv(struct tcb *tcp, const int flags_arg) printfd(tcp, tcp->u_arg[0]); tprints(", "); } else { - tprint_iov_upto(tcp, tcp->u_arg[2], tcp->u_arg[1], IOV_DECODE_STR, - tcp->u_rval); + tprint_iov_upto(tcp, tcp->u_arg[2], tcp->u_arg[1], + syserror(tcp) ? IOV_DECODE_ADDR : + IOV_DECODE_STR, tcp->u_rval); tprintf(", %lu, ", tcp->u_arg[2]); print_lld_from_low_high_val(tcp, 3); if (flags_arg >= 0) { diff --git a/scsi.c b/scsi.c index 979c3428..b3c62453 100644 --- a/scsi.c +++ b/scsi.c @@ -114,8 +114,8 @@ print_sg_io_v3_res(struct tcb *tcp, const long arg) if (sg_io.iovec_count) tprint_iov_upto(tcp, sg_io.iovec_count, (unsigned long) sg_io.dxferp, - IOV_DECODE_STR, - din_len); + syserror(tcp) ? IOV_DECODE_ADDR : + IOV_DECODE_STR, din_len); else print_sg_io_buffer(tcp, (unsigned long) sg_io.dxferp, din_len); @@ -190,6 +190,7 @@ print_sg_io_v4_res(struct tcb *tcp, const long arg) tprintf(", din[%u]=", din_len); if (sg_io.din_iovec_count) tprint_iov_upto(tcp, sg_io.din_iovec_count, sg_io.din_xferp, + syserror(tcp) ? IOV_DECODE_ADDR : IOV_DECODE_STR, din_len); else print_sg_io_buffer(tcp, sg_io.din_xferp, din_len); diff --git a/tests/preadv.c b/tests/preadv.c index eb53a5e9..2243eb87 100644 --- a/tests/preadv.c +++ b/tests/preadv.c @@ -82,7 +82,8 @@ main(void) if (preadv(0, iov, 1, -1) != -1) perror_msg_and_fail("preadv"); - printf("preadv(0, %p, 1, -1) = -1 EINVAL (%m)\n", iov); + printf("preadv(0, [{iov_base=%p, iov_len=%zu}], 1, -1) = " + "-1 EINVAL (%m)\n", iov->iov_base, iov->iov_len); if (preadv(0, NULL, 1, -2) != -1) perror_msg_and_fail("preadv");