print_array: enhance printing of unfetchable object addresses

When umoven_func invocation fails to fetch data, it prints the faulty
address.  If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].

Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself.  This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
 - tfetch_mem_func never prints anything;
 - tfetch_mem_func returns true if the fetch succeeded,
   and false otherwise.

* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics.  When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.

Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
This commit is contained in:
Дмитрий Левин 2018-05-29 01:15:19 +00:00
parent 143d007bbd
commit d54388e1ce
46 changed files with 89 additions and 89 deletions

4
aio.c
View File

@ -196,7 +196,7 @@ SYS_FUNC(io_submit)
printaddr(addr);
else
print_array(tcp, addr, nr, &iocbp, current_wordsize,
umoven_or_printaddr, print_iocbp, 0);
tfetch_mem, print_iocbp, 0);
return RVAL_DECODED;
}
@ -248,7 +248,7 @@ SYS_FUNC(io_getevents)
} else {
struct io_event buf;
print_array(tcp, tcp->u_arg[3], tcp->u_rval, &buf, sizeof(buf),
umoven_or_printaddr, print_io_event, 0);
tfetch_mem, print_io_event, 0);
tprints(", ");
/*
* Since the timeout parameter is read by the kernel

6
bpf.c
View File

@ -172,7 +172,7 @@ print_ebpf_prog(struct tcb *const tcp, const kernel_ulong_t addr,
struct ebpf_insn insn;
print_array(tcp, addr, len, &insn, sizeof(insn),
umoven_or_printaddr, print_ebpf_insn, &eid);
tfetch_mem, print_ebpf_insn, &eid);
}
}
@ -519,7 +519,7 @@ print_bpf_prog_info(struct tcb * const tcp, uint32_t bpf_fd,
print_big_u64_addr(info.map_ids);
print_array(tcp, info.map_ids, info.nr_map_ids,
&map_id_buf, sizeof(map_id_buf),
umoven_or_printaddr, print_uint64_array_member, 0);
tfetch_mem, print_uint64_array_member, 0);
PRINT_FIELD_IFINDEX(", ", info, ifindex);
PRINT_FIELD_DEV(", ", info, netns_dev);
@ -637,7 +637,7 @@ BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)
print_big_u64_addr(attr.prog_ids);
print_array(tcp, attr.prog_ids, attr.prog_cnt, &prog_id_buf,
sizeof(prog_id_buf), umoven_or_printaddr,
sizeof(prog_id_buf), tfetch_mem,
print_uint32_array_member, 0);
tprints(", prog_cnt=");

View File

@ -183,7 +183,7 @@ print_bpf_fprog(struct tcb *const tcp, const kernel_ulong_t addr,
struct bpf_filter_block filter;
print_array(tcp, addr, len, &filter, sizeof(filter),
umoven_or_printaddr, print_bpf_filter_block, &fbd);
tfetch_mem, print_bpf_filter_block, &fbd);
}
}

10
btrfs.c
View File

@ -301,7 +301,7 @@ btrfs_print_logical_ino_container(struct tcb *tcp,
tprints(", val=");
print_array(tcp, val_addr, container.elem_cnt / 3,
record, sizeof(record),
umoven_or_printaddr,
tfetch_mem,
print_btrfs_data_container_logical_ino, 0);
}
@ -340,7 +340,7 @@ btrfs_print_ino_path_container(struct tcb *tcp,
tprints(", val=");
print_array(tcp, val_addr, container.elem_cnt,
&offset, sizeof(offset),
umoven_or_printaddr,
tfetch_mem,
print_btrfs_data_container_ino_path, &val_addr);
}
@ -370,7 +370,7 @@ btrfs_print_qgroup_inherit(struct tcb *const tcp, const kernel_ulong_t qgi_addr)
tprints(", qgroups=");
print_array(tcp, qgi_addr + offsetof(typeof(inherit), qgroups),
inherit.num_qgroups, &record, sizeof(record),
umoven_or_printaddr, print_uint64_array_member, 0);
tfetch_mem, print_uint64_array_member, 0);
}
tprints("}");
}
@ -1158,7 +1158,7 @@ MPERS_PRINTER_DECL(int, btrfs_ioctl,
print_array(tcp, ptr_to_kulong(args.clone_sources),
args.clone_sources_count,
&record, sizeof(record),
umoven_or_printaddr,
tfetch_mem,
print_objectid_callback, 0);
}
btrfs_print_objectid(", ", args, parent_root);
@ -1201,7 +1201,7 @@ MPERS_PRINTER_DECL(int, btrfs_ioctl,
tprints(", spaces=");
print_array(tcp, arg + offsetof(typeof(args), spaces),
args.total_spaces,
&info, sizeof(info), umoven_or_printaddr,
&info, sizeof(info), tfetch_mem,
print_btrfs_ioctl_space_info, 0);
}
tprints("}");

14
defs.h
View File

@ -794,14 +794,14 @@ print_array(struct tcb *,
size_t nmemb,
void *elem_buf,
size_t elem_size,
int (*umoven_func)(struct tcb *,
kernel_ulong_t,
unsigned int,
void *),
bool (*tfetch_mem_func)(struct tcb *,
kernel_ulong_t addr,
unsigned int len,
void *laddr),
bool (*print_func)(struct tcb *,
void *elem_buf,
size_t elem_size,
void *opaque_data),
void *elem_buf,
size_t elem_size,
void *opaque_data),
void *opaque_data);
extern kernel_ulong_t *

2
dm.c
View File

@ -237,7 +237,7 @@ dm_decode_dm_target_deps(struct tcb *const tcp, const kernel_ulong_t addr,
tprints(", deps=");
print_array(tcp, addr + offset_end, s.count, &dev_buf, sizeof(dev_buf),
umoven_or_printaddr, dm_print_dev, NULL);
tfetch_mem, dm_print_dev, NULL);
tprints("}");

View File

@ -94,7 +94,7 @@ epoll_wait_common(struct tcb *tcp)
} else {
struct epoll_event ev;
print_array(tcp, tcp->u_arg[1], tcp->u_rval, &ev, sizeof(ev),
umoven_or_printaddr, print_epoll_event, 0);
tfetch_mem, print_epoll_event, 0);
tprintf(", %d, %d", (int) tcp->u_arg[2], (int) tcp->u_arg[3]);
}
}

View File

@ -185,7 +185,7 @@ file_ioctl(struct tcb *const tcp, const unsigned int code,
rc = print_array(tcp, arg + offsetof(typeof(args), info),
args.dest_count, &info, sizeof(info),
umoven_or_printaddr,
tfetch_mem,
print_file_dedupe_range_info, limit);
tprints("}");
@ -233,7 +233,7 @@ file_ioctl(struct tcb *const tcp, const unsigned int code,
print_array(tcp,
arg + offsetof(typeof(args), fm_extents),
args.fm_mapped_extents, &fe, sizeof(fe),
umoven_or_printaddr,
tfetch_mem,
print_fiemap_extent, 0);
}
tprints("}");

2
io.c
View File

@ -123,7 +123,7 @@ tprint_iov_upto(struct tcb *const tcp, const kernel_ulong_t len,
};
print_array(tcp, addr, len, iov, current_wordsize * 2,
umoven_or_printaddr_ignore_syserror, print_iovec, &config);
tfetch_mem_ignore_syserror, print_iovec, &config);
}
SYS_FUNC(readv)

View File

@ -64,7 +64,7 @@ tprint_sembuf_array(struct tcb *const tcp, const kernel_ulong_t addr,
#if defined HAVE_SYS_SEM_H || defined HAVE_LINUX_SEM_H
struct sembuf sb;
print_array(tcp, addr, count, &sb, sizeof(sb),
umoven_or_printaddr, print_sembuf, 0);
tfetch_mem, print_sembuf, 0);
#else
printaddr(addr);
#endif

View File

@ -76,7 +76,7 @@ print_kexec_segments(struct tcb *const tcp, const kernel_ulong_t addr,
const size_t sizeof_seg = ARRAY_SIZE(seg) * current_wordsize;
print_array(tcp, addr, len, seg, sizeof_seg,
umoven_or_printaddr, print_seg, 0);
tfetch_mem, print_seg, 0);
}
SYS_FUNC(kexec_load)

2
mem.c
View File

@ -360,7 +360,7 @@ SYS_FUNC(subpage_prot)
unsigned int entry;
print_array(tcp, map, nmemb, &entry, sizeof(entry),
umoven_or_printaddr, print_protmap_entry, 0);
tfetch_mem, print_protmap_entry, 0);
return RVAL_DECODED;
}

View File

@ -34,18 +34,13 @@
#include "xstring.h"
#include <limits.h>
static int
fetch_struct_mmsghdr_or_printaddr(struct tcb *const tcp,
static bool
fetch_struct_mmsghdr_for_print(struct tcb *const tcp,
const kernel_ulong_t addr,
const unsigned int len, void *const mh)
{
if ((entering(tcp) || !syserror(tcp))
&& fetch_struct_mmsghdr(tcp, addr, mh)) {
return 0;
} else {
printaddr(addr);
return -1;
}
return (entering(tcp) || !syserror(tcp)) &&
fetch_struct_mmsghdr(tcp, addr, mh);
}
struct print_struct_mmsghdr_config {
@ -146,7 +141,7 @@ decode_mmsgvec(struct tcb *const tcp, const kernel_ulong_t addr,
}
print_array(tcp, addr, vlen, &mmsg, sizeof_struct_mmsghdr(),
fetch_struct_mmsghdr_or_printaddr,
fetch_struct_mmsghdr_for_print,
print_struct_mmsghdr, &c);
}

2
net.c
View File

@ -739,7 +739,7 @@ print_getsockopt(struct tcb *const tcp, const unsigned int level,
uint32_t buf;
print_array(tcp, addr, MIN(ulen, rlen) / sizeof(buf),
&buf, sizeof(buf),
umoven_or_printaddr, print_uint32, 0);
tfetch_mem, print_uint32, 0);
break;
}
default:

View File

@ -473,7 +473,7 @@ decode_nlmsgerr_attr_cookie(struct tcb *const tcp,
const size_t nmemb = len / sizeof(cookie);
print_array(tcp, addr, nmemb, &cookie, sizeof(cookie),
umoven_or_printaddr, print_cookie, 0);
tfetch_mem, print_cookie, 0);
return true;
}

View File

@ -98,7 +98,7 @@ decode_netlink_diag_groups(struct tcb *const tcp,
return false;
print_array(tcp, addr, nmemb, &buf, current_wordsize,
umoven_or_printaddr, print_group, 0);
tfetch_mem, print_group, 0);
return true;
}

View File

@ -121,7 +121,7 @@ decode_packet_diag_mclist(struct tcb *const tcp,
return false;
print_array(tcp, addr, nmemb, &dml, sizeof(dml),
umoven_or_printaddr, print_packet_diag_mclist, 0);
tfetch_mem, print_packet_diag_mclist, 0);
return true;
}

View File

@ -107,7 +107,7 @@ decode_unix_diag_inode(struct tcb *const tcp,
return false;
print_array(tcp, addr, nmemb, &inode, sizeof(inode),
umoven_or_printaddr, print_inode, 0);
tfetch_mem, print_inode, 0);
return true;
}

View File

@ -192,7 +192,7 @@ decode_nla_meminfo(struct tcb *const tcp,
unsigned int count = 0;
print_array(tcp, addr, nmemb, &mem, sizeof(mem),
umoven_or_printaddr, print_uint32_array_member, &count);
tfetch_mem, print_uint32_array_member, &count);
return true;
}

8
numa.c
View File

@ -59,7 +59,7 @@ print_nodemask(struct tcb *const tcp, const kernel_ulong_t addr,
kernel_ulong_t buf;
print_array(tcp, addr, nmemb, &buf, current_wordsize,
umoven_or_printaddr, print_node, 0);
tfetch_mem, print_node, 0);
}
SYS_FUNC(migrate_pages)
@ -166,14 +166,14 @@ SYS_FUNC(move_pages)
if (entering(tcp)) {
tprintf("%d, %" PRI_klu ", ", (int) tcp->u_arg[0], npages);
print_array(tcp, tcp->u_arg[2], npages, &buf, current_wordsize,
umoven_or_printaddr, print_addr, 0);
tfetch_mem, print_addr, 0);
tprints(", ");
print_array(tcp, tcp->u_arg[3], npages, &buf, sizeof(int),
umoven_or_printaddr, print_int, 0);
tfetch_mem, print_int, 0);
tprints(", ");
} else {
print_array(tcp, tcp->u_arg[4], npages, &buf, sizeof(int),
umoven_or_printaddr, print_status, 0);
tfetch_mem, print_status, 0);
tprints(", ");
printflags(move_pages_flags, tcp->u_arg[5], "MPOL_???");
}

View File

@ -67,7 +67,7 @@ perf_ioctl_query_bpf(struct tcb *const tcp, const kernel_ulong_t arg)
print_array(tcp, arg + offsetof(struct perf_event_query_bpf, ids), info,
&info, sizeof(info),
umoven_or_printaddr, print_uint32_array_member, NULL);
tfetch_mem, print_uint32_array_member, NULL);
tprints("}");

2
poll.c
View File

@ -57,7 +57,7 @@ decode_poll_entering(struct tcb *tcp)
struct pollfd fds;
print_array(tcp, addr, nfds, &fds, sizeof(fds),
umoven_or_printaddr, print_pollfd, 0);
tfetch_mem, print_pollfd, 0);
tprintf(", %u, ", nfds);
}

View File

@ -277,5 +277,5 @@ MPERS_PRINTER_DECL(void, print_siginfo_array, struct tcb *const tcp,
siginfo_t si;
print_array(tcp, addr, len, &si, sizeof(si),
umoven_or_printaddr, print_siginfo_t, 0);
tfetch_mem, print_siginfo_t, 0);
}

View File

@ -259,7 +259,7 @@ decode_tca_stab_data(struct tcb *const tcp,
return false;
print_array(tcp, addr, nmemb, &data, sizeof(data),
umoven_or_printaddr, print_stab_data, NULL);
tfetch_mem, print_stab_data, NULL);
return true;
}

2
sock.c
View File

@ -310,7 +310,7 @@ decode_ifconf(struct tcb *const tcp, const kernel_ulong_t addr)
print_array(tcp, ptr_to_kulong(ifc->ifc_buf),
ifc->ifc_len / sizeof(struct_ifreq),
&ifr, sizeof(ifr),
umoven_or_printaddr, print_ifconf_ifreq, NULL);
tfetch_mem, print_ifconf_ifreq, NULL);
}
tprints("}");

View File

@ -335,7 +335,7 @@ main(void)
"}, {aio_key=%u, aio_lio_opcode=IOCB_CMD_PWRITEV"
", aio_reqprio=%hd, aio_fildes=%d, aio_buf=%#" PRI__x64
", aio_nbytes=%" PRI__u64 ", aio_offset=%" PRI__d64
"}, {NULL}, {%#lx}, %p]) = %s\n",
"}, {NULL}, {%#lx}, ... /* %p */]) = %s\n",
*ctx, 1057L,
cbv2[0].aio_data, cbv2[0].aio_key,
cbv2[0].aio_lio_opcode, cbv2[0].aio_fildes,

View File

@ -918,7 +918,8 @@ print_BPF_PROG_QUERY_attr5(const struct bpf_attr_check *check, unsigned long add
", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
", attach_flags=BPF_F_ALLOW_MULTI|0xbeefcafc"
#if defined(INJECT_RETVAL) && INJECT_RETVAL > 0
", prog_ids=[0, 1, 4294967295, 2718281828, %p], prog_cnt=5}",
", prog_ids=[0, 1, 4294967295, 2718281828, ... /* %p */]"
", prog_cnt=5}",
prog_load_ids_ptr + ARRAY_SIZE(prog_load_ids)
#else
", prog_ids=%p, prog_cnt=5}", prog_load_ids_ptr

View File

@ -143,7 +143,7 @@ main(int argc, char **argv)
u32_arr[1] = 5;
assert(ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_arr) == inject_retval);
printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, {ids_len=3134983661"
", prog_cnt=5, ids=[3737845741, 3735928559, %p]})"
", prog_cnt=5, ids=[3737845741, 3735928559, ... /* %p */]})"
" = %ld (INJECTED)\n",
u32_efault, inject_retval);

View File

@ -898,7 +898,7 @@ main(void)
", {ctrl_class=V4L2_CTRL_CLASS_MPEG, count=%u, controls="
"[{id=V4L2_CID_BRIGHTNESS, size=0, value=%d, value64=%lld}"
", {id=V4L2_CID_CONTRAST, size=2, string=\"\\377\\377\"}"
", %p]}) = -1 EBADF (%m)\n",
", ... /* %p */]}) = -1 EBADF (%m)\n",
p_ext_controls->count,
p_ext_controls->controls[0].value,
(long long) p_ext_controls->controls[0].value64,

View File

@ -129,7 +129,7 @@ main(void)
printf("{buf=%p, bufsz=%zu, mem=%p, memsz=%zu}, ",
segms[i].buf, segms[i].bufsz,
segms[i].mem, segms[i].memsz);
printf("%p], %s%s) = %s\n",
printf("... /* %p */], %s%s) = %s\n",
segms + NUM_SEGMS,
sizeof(long) == 8 ? flags[0].str64 : flags[0].str32,
flags[0].str, errstr);

View File

@ -152,7 +152,7 @@ test_mmsg_name(const int send_fd, const int recv_fd)
printf("sendmmsg(-1, [{msg_hdr=");
print_msghdr(&send_mh[IOV_MAX].msg_hdr, 0);
errno = saved_errno;
printf("}, %p], %u, MSG_DONTWAIT) = %d %s (%m)\n",
printf("}, ... /* %p */], %u, MSG_DONTWAIT) = %d %s (%m)\n",
&send_mh[IOV_MAX1], 2, rc, errno2name());
rc = send_mmsg(send_fd, send_mh, IOV_MAX1, MSG_DONTWAIT);

View File

@ -63,7 +63,7 @@ print_page_array(const void **const pages,
break;
}
} else {
printf("%p", pages + i);
printf("... /* %p */", pages + i);
break;
}
const void *const addr = pages[i];
@ -99,7 +99,7 @@ print_node_array(const int *const nodes,
break;
}
} else {
printf("%p", nodes + i);
printf("... /* %p */", nodes + i);
break;
}
printf("%d", nodes[i]);

View File

@ -95,7 +95,7 @@ print_pollfd_array_entering(const struct pollfd *const pfd,
if (i)
tprintf(", ");
if (i >= valid) {
tprintf("%p", &pfd[i]);
tprintf("... /* %p */", &pfd[i]);
break;
}
if (i >= abbrev) {

View File

@ -99,7 +99,7 @@ main(void)
tprintf("pwritev(1, [], 0, 0) = 0\n");
rc = pwritev(1, w_iov + ARRAY_SIZE(w_iov_) - 1, 2, 0);
tprintf("pwritev(1, [{iov_base=\"%s\", iov_len=%u}, %p], 2, 0)"
tprintf("pwritev(1, [{iov_base=\"%s\", iov_len=%u}, ... /* %p */], 2, 0)"
" = %ld %s (%m)\n",
w2_c, LENGTH_OF(w2_c), w_iov + ARRAY_SIZE(w_iov_),
rc, errno2name());

View File

@ -104,7 +104,7 @@ dumpio(void)
tprintf("pwritev2(1, [], 0, 0, 0) = 0\n");
rc = pw(1, w_iov + ARRAY_SIZE(w_iov_) - 1, 2, 0);
tprintf("pwritev2(1, [{iov_base=\"%s\", iov_len=%u}, %p], 2, 0, 0)"
tprintf("pwritev2(1, [{iov_base=\"%s\", iov_len=%u}, ... /* %p */], 2, 0, 0)"
" = %ld %s (%m)\n",
w2_c, LENGTH_OF(w2_c), w_iov + ARRAY_SIZE(w_iov_),
rc, errno2name());

View File

@ -135,7 +135,7 @@ print_iov(const struct iovec *iov, const void *arg_ptr, long rc)
}
if (arg->addr_term)
printf(", %p", iov + arg->count);
printf(", ... /* %p */", iov + arg->count);
printf("]");
}

View File

@ -65,7 +65,7 @@ print_iovec(const struct iovec *iov, unsigned int cnt, unsigned int size)
if (i)
fputs(", ", stdout);
if (i == size) {
printf("%p", &iov[i]);
printf("... /* %p */", &iov[i]);
break;
}
if (i == LIM) {

View File

@ -89,7 +89,7 @@ main(void)
fds[1], (long) writev(fds[1], w_iov, 0));
rc = writev(fds[1], w_iov + ARRAY_SIZE(w_iov_) - 1, 2);
tprintf("writev(%d, [{iov_base=\"%s\", iov_len=%u}, %p], 2)"
tprintf("writev(%d, [{iov_base=\"%s\", iov_len=%u}, ... /* %p */], 2)"
" = %ld %s (%m)\n",
fds[1], w2_c, LENGTH_OF(w2_c), w_iov + ARRAY_SIZE(w_iov_),
rc, errno2name());

View File

@ -118,7 +118,7 @@ main(void)
prog->len = 3;
syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, 0, prog);
tprintf("seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=%u"
", filter=[%s, %p]}) = -1 EFAULT (%m)\n",
", filter=[%s, ... /* %p */]}) = -1 EFAULT (%m)\n",
prog->len, kill_stmt_txt, filter + ARRAY_SIZE(filter_c));
prog->len = 0;

View File

@ -64,7 +64,7 @@ main(void)
sem_b2->sem_flg = 0xbeef;
rc = semop(bogus_semid, sem_b2, 2);
printf("semop(%d, [{%hu, %hd, %s%s%#hx}, %p], %u) = %s\n",
printf("semop(%d, [{%hu, %hd, %s%s%#hx}, ... /* %p */], %u) = %s\n",
bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",
sem_b2->sem_flg & IPC_NOWAIT ? "IPC_NOWAIT|" : "",
@ -91,7 +91,7 @@ main(void)
ts->tv_sec = 1;
ts->tv_nsec = 123456789;
rc = semtimedop(bogus_semid, sem_b2, 2, ts);
printf("semtimedop(%d, [{%hu, %hd, %s%s%#hx}, %p], %u"
printf("semtimedop(%d, [{%hu, %hd, %s%s%#hx}, ... /* %p */], %u"
", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",

View File

@ -76,7 +76,7 @@ print_nodes(const unsigned long maxnode, unsigned int offset)
printf("%#0*lx", (int) sizeof(long) * 2 + 2,
nodemask[i]);
} else {
printf("%p", nodemask + i);
printf("... /* %p */", nodemask + i);
break;
}
}

View File

@ -115,7 +115,7 @@ main(void)
errstr = sprintrc(rc);
printf("%s(2, [", SYSCALL_NAME);
printuid(*g1);
printf(", %p]) = %s\n", g1 + 1, errstr);
printf(", ... /* %p */]) = %s\n", g1 + 1, errstr);
g2[0] = -2;
g2[1] = -3;
@ -133,7 +133,7 @@ main(void)
printuid(g2[0]);
printf(", ");
printuid(g2[1]);
printf(", %p]) = %s\n", g2 + 2, errstr);
printf(", ... /* %p */]) = %s\n", g2 + 2, errstr);
g3[0] = 0;
g3[1] = 1;

View File

@ -186,7 +186,7 @@ print_nlattr(const unsigned int nla_len, const char *const nla_type)
if (i) printf(", "); \
(print_elem_)(&(obj_)[i], i); \
} \
printf(", %p]", \
printf(", ... /* %p */]", \
RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_))) \
+ sizeof(obj_) - sizeof((obj_)[0]))); \
/* sizeof(obj_) */ \
@ -308,7 +308,7 @@ print_nlattr(const unsigned int nla_len, const char *const nla_type)
if (i) printf(", "); \
(print_elem_)(&(obj_)[i]); \
} \
printf(", %p]}", \
printf(", ... /* %p */]}", \
RTA_DATA(TEST_NLATTR_nla) \
+ sizeof((obj_)[0]))); \
/* sizeof(obj_) */ \

2
uid.c
View File

@ -180,7 +180,7 @@ print_groups(struct tcb *const tcp, const unsigned int len,
uid_t gid;
print_array(tcp, addr, len, &gid, sizeof(gid),
umoven_or_printaddr, print_gid, 0);
tfetch_mem, print_gid, 0);
}
SYS_FUNC(setgroups)

30
util.c
View File

@ -1060,8 +1060,8 @@ print_uint64_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
*
* Array elements are being fetched to the address specified by elem_buf.
*
* The fetcher callback function specified by umoven_func should follow
* the same semantics as umoven_or_printaddr function.
* The fetcher callback function specified by tfetch_mem_func should follow
* the same semantics as tfetch_mem function.
*
* The printer callback function specified by print_func is expected
* to print something; if it returns false, no more iterations will be made.
@ -1073,9 +1073,7 @@ print_uint64_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
* - "NULL", if start_addr is NULL;
* - "[]", if nmemb is 0;
* - start_addr, if nmemb * elem_size overflows or wraps around;
* - nothing, if the first element cannot be fetched
* (if umoven_func returns non-zero), but it is assumed that
* umoven_func has printed the address it failed to fetch data from;
* - start_addr, if the first tfetch_mem_func invocation returned false;
* - elements of the array, delimited by ", ", with the array itself
* enclosed with [] brackets.
*
@ -1084,9 +1082,8 @@ print_uint64_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
* - "..." is printed instead of max_strlen+1 element
* and no more iterations will be made.
*
* This function returns true only if
* - umoven_func has been called at least once AND
* - umoven_func has not returned false.
* This function returns true only if tfetch_mem_func has returned true
* at least once.
*/
bool
print_array(struct tcb *const tcp,
@ -1094,10 +1091,10 @@ print_array(struct tcb *const tcp,
const size_t nmemb,
void *const elem_buf,
const size_t elem_size,
int (*const umoven_func)(struct tcb *,
kernel_ulong_t,
unsigned int,
void *),
bool (*const tfetch_mem_func)(struct tcb *,
kernel_ulong_t addr,
unsigned int len,
void *laddr),
bool (*const print_func)(struct tcb *,
void *elem_buf,
size_t elem_size,
@ -1131,8 +1128,15 @@ print_array(struct tcb *const tcp,
if (cur != start_addr)
tprints(", ");
if (umoven_func(tcp, cur, elem_size, elem_buf))
if (!tfetch_mem_func(tcp, cur, elem_size, elem_buf)) {
if (cur == start_addr)
printaddr(cur);
else {
tprints("...");
printaddr_comment(cur);
}
break;
}
if (cur == start_addr)
tprints("[");

4
v4l2.c
View File

@ -270,7 +270,7 @@ print_v4l2_format_fmt(struct tcb *const tcp, const char *prefix,
tprintf(", chromakey=%#x, clips=", f->fmt.win.chromakey);
ret = print_array(tcp, ptr_to_kulong(f->fmt.win.clips),
f->fmt.win.clipcount, &clip, sizeof(clip),
umoven_or_printaddr, print_v4l2_clip, 0);
tfetch_mem, print_v4l2_clip, 0);
tprintf(", clipcount=%u, bitmap=", f->fmt.win.clipcount);
printaddr(ptr_to_kulong(f->fmt.win.bitmap));
#ifdef HAVE_STRUCT_V4L2_WINDOW_GLOBAL_ALPHA
@ -853,7 +853,7 @@ print_v4l2_ext_controls(struct tcb *const tcp, const kernel_ulong_t arg,
struct_v4l2_ext_control ctrl;
bool fail = !print_array(tcp, ptr_to_kulong(c.controls), c.count,
&ctrl, sizeof(ctrl),
umoven_or_printaddr_ignore_syserror,
tfetch_mem_ignore_syserror,
print_v4l2_ext_control, 0);
if (exiting(tcp) && syserror(tcp))