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.
This commit is contained in:
Eugene Syromyatnikov 2016-10-15 02:30:47 +03:00 committed by Dmitry V. Levin
parent a980c9ebbd
commit 030b61c92f
3 changed files with 10 additions and 6 deletions

8
io.c
View File

@ -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) {

5
scsi.c
View File

@ -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);

View File

@ -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");