From: Eugene Syromyatnikov Date: Tue, 16 Jul 2019 00:06:02 +0000 (+0200) Subject: Add support for printing local arrays to print_array X-Git-Tag: v5.3~15 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c5af330802caf0092a10cc099c93e717420b5f4b;p=strace Add support for printing local arrays to print_array * defs.h (print_array_ex): Describe parameters. (print_local_array): A wrapper for printing arrays in local memory via print_array_ex. * util.c (print_array_ex): Handle case of NULL tfetch_mem_func by printing elements of array in local memory pointed by start_addr parameter. --- diff --git a/defs.h b/defs.h index 337c9bd7..ccfe673c 100644 --- a/defs.h +++ b/defs.h @@ -852,8 +852,29 @@ typedef const char * (*sprint_obj_by_addr_fn)(struct tcb *, kernel_ulong_t); /** - * @param flags Combination of xlat style settings and additional flags from - * enum print_array_flags. + * Array printing function with over-engineered interface. + * + * @param start_addr If tfetch_mem_fn is non-NULL: address in tracee's + * memory where the start of the array is located. + * If tfetch_mem_fn is NULL: ignored. + * @param nmemb Number of elements in array. + * @param elem_buf If tfetch_mem_fn is non-NULL: a buffer where each + * element fetched by tfetch_mem_fn is stored. + * If tfetch_mem_fn is NULL: address of the start of + * the array in local memory. + * @param elem_size Size (in bytes) of each element in the array. + * @param tfetch_mem_fn Fetching function. If NULL, then elem_buf is treated + * as local array of nmemb members elem_size each; + * start_addr is ignored. + * @param print_func Element printing callback. + * @param opaque_data A value that is unconditionally passed to print_func + * in opaque_data argument. + * @param flags Combination of xlat style settings and additional + * flags from enum print_array_flags. + * @param index_xlat Xlat array that is used for printing indices. + * @param index_xlat_size The size of xlat array. + * @param index_dflt Default string for the values not found + * in index_xlat. */ extern bool print_array_ex(struct tcb *, @@ -868,6 +889,7 @@ print_array_ex(struct tcb *, const struct xlat *index_xlat, const char *index_dflt); +/** Print an array from tracee's memory without any index printing features. */ static inline bool print_array(struct tcb *const tcp, const kernel_ulong_t start_addr, @@ -883,6 +905,22 @@ print_array(struct tcb *const tcp, 0, NULL, NULL); } +/** Shorthand for printing local arrays. */ +static inline bool +print_local_array(struct tcb *tcp, + void *start_addr, + const size_t nmemb, + void *const elem_buf, + const size_t elem_size, + print_fn print_func, + void *const opaque_data, + unsigned int flags) +{ + return print_array_ex(tcp, (uintptr_t) start_addr , nmemb, + elem_buf, elem_size, NULL, print_func, + opaque_data, flags, NULL, NULL); +} + extern kernel_ulong_t * fetch_indirect_syscall_args(struct tcb *, kernel_ulong_t addr, unsigned int n_args); diff --git a/util.c b/util.c index 34561c47..db733b83 100644 --- a/util.c +++ b/util.c @@ -1275,7 +1275,7 @@ bool print_array_ex(struct tcb *const tcp, const kernel_ulong_t start_addr, const size_t nmemb, - void *const elem_buf, + void *elem_buf, const size_t elem_size, tfetch_mem_fn tfetch_mem_func, print_fn print_func, @@ -1298,7 +1298,10 @@ print_array_ex(struct tcb *const tcp, const kernel_ulong_t end_addr = start_addr + size; if (end_addr <= start_addr || size / elem_size != nmemb) { - printaddr(start_addr); + if (tfetch_mem_func) + printaddr(start_addr); + else + tprints("???"); return false; } @@ -1313,14 +1316,18 @@ print_array_ex(struct tcb *const tcp, if (cur != start_addr) tprints(", "); - if (!tfetch_mem_func(tcp, cur, elem_size, elem_buf)) { - if (cur == start_addr) - printaddr(cur); - else { - tprints("..."); - printaddr_comment(cur); + if (tfetch_mem_func) { + if (!tfetch_mem_func(tcp, cur, elem_size, elem_buf)) { + if (cur == start_addr) + printaddr(cur); + else { + tprints("..."); + printaddr_comment(cur); + } + break; } - break; + } else { + elem_buf = (void *) (uintptr_t) cur; } if (cur == start_addr)