Dmitry V. Levin [Tue, 23 Jan 2018 21:17:05 +0000 (21:17 +0000)]
tests: add file:line to perror_msg_and_fail/error_msg_and_fail output
* tests/tests.h [!perror_msg_and_fail] (perror_msg_and_fail): New macro
wrapper around the homonymous function.
[!error_msg_and_fail] (error_msg_and_fail): Likewise.
* tests/error_msg.c (perror_msg_and_fail, error_msg_and_fail): New
macros defined to themselves.
Dmitry V. Levin [Sun, 21 Jan 2018 23:23:31 +0000 (23:23 +0000)]
Transform fetch_old_mmap_args into fetch_indirect_syscall_args
As there are more than one old style syscall that take their arguments
via array, generalize fetch_old_mmap_args into a function that could
fetch variable number of arguments.
* mem.c (fetch_old_mmap_args): Transform into ...
* fetch_indirect_syscall_args.c: ... fetch_indirect_syscall_args
in this new file.
* Makefile.am (libstrace_a_SOURCES): Add it.
* defs.h [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): Remove.
(fetch_indirect_syscall_args): New prototype.
* pathtrace.c (pathtrace_match_set) [HAVE_ARCH_OLD_MMAP]: Use
fetch_indirect_syscall_args instead of fetch_old_mmap_args.
Dmitry V. Levin [Sun, 21 Jan 2018 20:19:53 +0000 (20:19 +0000)]
Move decoder of getpagesize syscall to libstrace
As only five architectures have getpagesize syscall, moving the decoder
to libstrace allows to get rid of getpagesize related ifdefs and check
build of getpagesize decoder on other architectures.
* mem.c (SYS_FUNC(getpagesize)): Move ...
* getpagesize.c: ... to this new file.
* Makefile.am (libstrace_a_SOURCES): Add it.
Some old systems that still make some sense to be supported have only
gawk 3, so let's support them for now.
In order to achieve that, multiple changes have been implemented:
- Multidimensional arrays are replaced with single-dimensional ones.
In most places it's a "][" -> ", " replacement, as awk allows some
kind of emulation of multidimensional arrays that way, but in several
occasions (specifically for storing name and special fields) we have
to iterate over them later, so we store that information in
additional arrays in order to get the keys.
- "switch" statements are replaced with sets of "if ... else if ...
else" statements. This change is trivial, except we've added
a temporary variable in what_is order to store expression value, for
readability purposes.
- No support for array iteration ordering. This one is most ugly of
them all. Luckily, not that ugly, we've just had to process index a
bit in order to make it lexicographically sortable and add two
temporary arrays containing sorted indices in order to sort over them
instead of those two arrays that we've added in order to work around
lack of multidimensional array support.
* mpers.awk (compare_indices): Remove unused function.
(array_get, update_upper_bound, /^DW_AT_data_member_location/,
/^DW_AT_byte_size/, /^DW_AT_encoding/): Replace multidimensional array
access with comma-concatenated index.
(norm_idx): New function.
(array_seq): Replace multidimensional array access with
comma-concatenated index. Use comma-concatenated pair of (array_idx,
"seq") in order to check presence of the item in an array.
(what_is): Add enc and i local variables. Store the value of
array[what_idx, "encoding"] in it. Replace "switch" statements with
sets of "if ... else if ... else" statements. Replace multidimensional
array access with comma-concatenated index. Use for (... ; ...; ...)
iteration over aparents_keys instead of iteration over array.
(/^<[[:xdigit:]]+>/): Store idx as norm_idx(matches[2]). Replace
multidimensional array access with comma-concatenated index. Store an
additional flag in array_names array.
(/^DW_AT_name/): Replace multidimensional array access with
comma-concatenated index. Add a flag to array_names for that idx.
(/^DW_AT_type/): Do not capture "0x" as a part of a group, normalise
the captured group. Replace multidimensional array access with
comma-concatenated index.
(/^Abbrev Number:[^(]+\(DW_TAG_/): Replace multidimensional array access
with comma-concatenated index. Store additional flags in
array_special and array_parents arrays.
(END): Remove PROCINFO["sorted_in"] setup. Sort array_parents. Replace
multidimensional array access with comma-concatenated index. Iterate
over array_special to go over all the items that have "special" field.
Iterate over array_names to go over all items that have "name" field.
* NEWS: Mention it.
dm: add support for event_nr in DM_LIST_DEVICES result
Commit v4.13-rc1~137^2~13 (and a follow-up fix v4.14-rc4~20^2~3
that changed alignment) introduced an additional hidden field
in the structure returned by DM_LIST_DEVICES ioctl command
that contains event_nr information.
Unfortunately, we can't test it for now, but looks like it kinda works:
* dm.c (dm_decode_dm_name_list): Obtain the amount of bytes copied
during printing device name, print event number if there's a suitable
gap present and the DM version is high enough.
* NEWS: Mention it.
Dmitry V. Levin [Sun, 21 Jan 2018 01:46:04 +0000 (01:46 +0000)]
Use #if idiom instead of #ifdef for HAVE_ARCH_* macros.
* linux/arch_defs_.h [!HAVE_ARCH_OLD_MMAP] (HAVE_ARCH_OLD_MMAP): New
macro.
[!HAVE_ARCH_OLD_MMAP_PGOFF] (HAVE_ARCH_OLD_MMAP_PGOFF): Likewise.
* defs.h: Use #if instead of #ifdef to check HAVE_ARCH_OLD_MMAP.
* mem.c: Use #if instead of #ifdef to check HAVE_ARCH_OLD_MMAP
and HAVE_ARCH_OLD_MMAP_PGOFF
* pathtrace.c: Likewise.
Dmitry V. Levin [Sun, 21 Jan 2018 01:46:04 +0000 (01:46 +0000)]
Rename arch-specific arch_defs.h files to arch_defs_.h
Introduce a new arch_defs.h header that includes the corresponding
arch-specific arch_defs_.h file followed by generic arch_defs_.h file.
* linux/arch_defs.h: Rename to linux/arch_defs_.h.
* linux/aarch64/arch_defs.h: Rename to linux/aarch64/arch_defs_.h.
* linux/arm/arch_defs.h: Rename to linux/arm/arch_defs_.h.
* linux/i386/arch_defs.h: Rename to linux/i386/arch_defs_.h.
* linux/m68k/arch_defs.h: Rename to linux/m68k/arch_defs_.h.
* linux/s390/arch_defs.h: Rename to linux/s390/arch_defs_.h.
* linux/s390x/arch_defs.h: Rename to linux/s390x/arch_defs_.h.
* linux/x32/arch_defs.h: Rename to linux/x32/arch_defs_.h.
* linux/x86_64/arch_defs.h: Rename to linux/x86_64/arch_defs_.h.
* arch_defs.h: New file.
* Makefile.am (strace_SOURCES): Add it.
(EXTRA_DIST): Rename linux/*/arch_defs.h to linux/*/arch_defs_.h.
As umovestr now returns something useful, let's propagate it further.
* defs.h (printstr_ex, printpathn, printpath): Change return type from
void to int.
(printstrn, printstr): Change return type from void to int, return
printstr_ex result.
* util.c (printpathn): Return -1 on NULL addr, nul_seen (exit code of
umovestr) on success.
(printpath): Return printpathn result.
(printstr_ex): Return -1 on NULL addr, umoven/umovestr result otherwise.
We return the size that includes \0 in order to preserve existing
behaviour (return 0 when \0 haven't been seen, return positive number
when it has been seen).
* ucopy.c (umovestr_peekdata, umovestr): Return string length
including \0 instead of 1 when \0 is found.
Dmitry V. Levin [Fri, 19 Jan 2018 17:07:04 +0000 (17:07 +0000)]
mpers.awk: avoid redefinition of mpers_ptr_t
Older versions of gcc like those found in RHEL6 fail with the following
diagnostics:
In file included from block.c:32:
./mpers-m32/struct_blk_user_trace_setup.h:2: error: redefinition of typedef ‘mpers_ptr_t’
mpers_type.h:44: note: previous declaration of ‘mpers_ptr_t’ was here
* configure.ac (AC_ARG_ENABLE([mpers])): Allow m32 and mx32 values
for --enable-mpers option.
* m4/mpers.m4 (st_MPERS): Check for personality support if personality
name is provided as an option. Fail if the requested personality
support is not available.
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
strace.1.in: clarify mpers flags in strace -V output
The previous description was a bit dated.
* strace.1.in (.SH "MULTIPLE PERSONALITY SUPPORT"): Remove "no-m32" and
"no-mx32", describe the situation when some of mpers flags are not
present in strace -V output.
Dmitry V. Levin [Wed, 17 Jan 2018 21:31:07 +0000 (21:31 +0000)]
tests: check path tracing of ppoll syscall
* tests/ppoll.c (main) [PATH_TRACING_FD]: Skip if /proc/self/fd/
is not available. Add a test call that use PATH_TRACING_FD.
(main): Conditionalize expected output for those calls
that do not use PATH_TRACING_FD with [!PATH_TRACING_FD].
* tests/ppoll-P.c: New file.
* tests/pure_executables.list: Add ppoll-P.
* tests/.gitignore: Likewise.
* tests/gen_tests.in (ppoll-P): New entry.
Dmitry V. Levin [Wed, 17 Jan 2018 21:31:07 +0000 (21:31 +0000)]
tests: check path tracing of poll syscall
* tests/poll.c (main) [PATH_TRACING_FD]: Skip if /proc/self/fd/
is not available. Add tests calls that use PATH_TRACING_FD.
(main): Conditionalize expected output for those calls
that do not use PATH_TRACING_FD with [!PATH_TRACING_FD].
* tests/poll-P.c: New file.
* tests/pure_executables.list: Add poll-P.
* tests/.gitignore: Likewise.
* tests/poll-P.test: New test.
* tests/Makefile.am (DECODER_TESTS): Add poll-P.test.
As s390x is the only 64-bit architecture that has old_mmap,
the test needs some adjustments there.
* tests/old_mmap.c: Update condition.
(main): Change int types to long, extend numerals to 64 bit, change
printing format qualifiers to corresponding long types.
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
* tests/old_mmap.c [!TEST_FD]: Define TEST_FD.
(main) <args1_c>: Replace 5th argument with TEST_FD.
(main): Wrap the output for the calls that do not use TEST_FD
with #ifndef PATH_TRACING.
* tests/old_mmap-P.c: New file.
* tests/pure_executables.list: Add old_mmap-P.
* tests/.gitignore: Likewise.
* tests/gen_tests.in: Add old_mmap-P test.
As these system calls have only one argument that points to the
location in memory containing actual arguments, current path tracing
implementation is incorrect. In order to fix this, let's use recently
introduced fetch_old_mmap_args in order to get actual arguments suitable
for path matching.
* pathtrace.c [HAVE_ARCH_OLD_MMAP] <case SEN_old_mmap,
case SEN_old_mmap_pgoff>: Retrieve actual old_mmap arguments with
fetch_old_mmap_args, pass the value from the retrieved args if it's
available.
Move common old_mmap/old_mmap_pgoff argument fetching code into a
separate function.
As it is, it also fixes the case of non-verbose printing of old_mmap
arguments (see the new test in the next commit). Also, it is a
preparation for the fix of path tracing for these syscalls.
* defs.h [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): New prototype.
* mem.c [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): New function.
[HAVE_ARCH_OLD_MMAP] (old_mmap, old_mmap_pgoff): Use it.
Fixes: 3db07f11 "Fix old_mmap output when mmap arguments are unfetchable" Suggested-by: Dmitry V. Levin <ldv@altlinux.org>
* linux/aarch64/arch_regs.c (ARCH_PERSONALITY_0_IOV_SIZE,
ARCH_PERSONALITY_1_IOV_SIZE): New macros.
* linux/aarch64/get_scno.c (arch_get_scno): Do not call
update_personality as it is handled by the generic get_regs code now.
syscall.c: add ability to set personality based on GETREGSET iov size
Some architectures (aarch64, s390x) use only PTRACE_GETREGSET interface
and use its size to detect current personality. Let's generalise this
approach and also avoid subtle errors when we get register but forget to
update personality, at least for those architectures.
Note that in order to employ this behaviour, architecture has to use
PTRACE_GETREGSET exclusively (no HAVE_GETREGS_OLD) and should declare
appropriate ARCH_PERSONALITY_*_IOV_SIZE macros.
* syscall.c (get_regs) [ptrace_getregset_or_getregs &&
!HAVE_GETREGS_OLD]: Call update_personality based on the value returned
in the iov_len field by PTRACE_GETREGSET. Warn once if the returned
iov_len is unknown.
syscall.c: add sanity check for the target personality number
We can never be cautious enough.
* defs.h (set_personality): Change argument type to unsigned int.
* syscall.c (set_personality): Change argument type to unsigned int,
check whether requested personality is sane, die otherwise.
syscall.c: move current_personality check to set_personality
As all the personality-dependent entries are initially in sync, we can
move the check whether we are setting the same personality as we
currently are inside set_personality out of update_personality.
* syscall.c (current_wordsize, current_klongsize): Initialise to 0'th
personality value in order to make the statement about "all the
personality-dependent entries are initially in sync" true.
(set_personality): Check whether requested personality differs from
current_personality.
(update_personality): Call set_personality unconditionally.
syscall.c: always update tcp->currpers in update_personality
Sometimes (for example, switching from a process with one personality
to a process that previously had different personality but returning
from execve to that same personality into) it is possible that
current_personality is not changed, but tcp->currpers is different.
So, let's not return from update_personality and always update
tcp->currpers if it differs from the target personality.
* syscall.c (update_personality): Do not exit early if personality ==
current_personality.
Add support for specifying compiler options for mpers builds
Because some architectures are very, very special.
* configure.ac (cc_flags_m32, cc_flags_mx32): New variables. AC_SUBST
them.
* m4/mpers.m4 (MPERS_CFLAGS): Use instead of CFLAG, pushdef as
$cc_flags_$1.
Use mpers_name instead of CFLAG in AC_CACHE_CHECK messages.
Pass MPERS_CFLAGS as the second argument to mpers_test.sh
* mpers.sh: Add CC_ARCH_FLAGS as the second argument (PARSER_FILE
is moved to the third one). Do not expect leading dash in ARCH_FLAG
anymore.
* mpers_test.sh (mpers_cc_flags): New variable, initialise to the second
command line argument.
Pass $mpers_name without leading dash to mpers.sh.
Pass $mpers_cc_flags as the second argument to mpers.sh ($sample is
the third argument now).
* Makefile.am (mpers-m%.stamp:): Pass $(mpers_CC_FLAGS) as the second
argument to mpers.sh ($$f is now the third argument).
($(mpers_m32_targets)): Define target variable mpers_CC_FLAGS with the
value of @cc_flags_m32@
($(mpers_mx32_targets)): Define target variable mpers_CC_FLAGS with the
value of @cc_flags_mx32@
* tests/Makefile.am (MERS_CC_FLAGS): New variable.
* bootstrap: Append @cc_flags_$1@ to MPERS_CC_FLAGS. Append
$(MPERS_CC_FLAGS) to ARCH_MFLAGS.
Dmitry V. Levin [Tue, 16 Jan 2018 04:34:25 +0000 (04:34 +0000)]
Enhance error diagnostics about invalid syscalls in fault injection syntax
Validate syscall set before the whole fault injection syntax.
* filter_qualify.c (parse_inject_expression): Add const qualifier to
return type. Return an empty string when no syscall set is specified.
(qualify_inject_common): Add const qualifier to "name". Move
qualify_syscall_tokens invocation right after parse_inject_expression.
* tests/qual_fault-syntax.test: Update expected output.
* tests/qual_inject-syntax.test: Likewise.
Dmitry V. Levin [Sun, 14 Jan 2018 00:43:12 +0000 (00:43 +0000)]
filter_qualify: move memory allocation from parse_inject_expression
* filter_qualify.c (parse_inject_expression): Replace "s" and "buf"
arguments with "str" argument, use it instead of "s" and "*buf".
(qualify_inject_common): Rename "buf" to "copy", initialize it to a copy
of "str", pass "copy" to parse_inject_expression instead of "str" and
"buf".
Dmitry V. Levin [Sat, 13 Jan 2018 13:46:45 +0000 (13:46 +0000)]
configure: use AC_MSG_ERROR and AC_MSG_FAILURE consistently
* configure.ac [$arch = mips]: Use AC_MSG_FAILURE instead of
AC_MSG_ERROR when _MIPS_SIM cannot be determined. Use AC_MSG_ERROR
instead of AC_MSG_FAILURE when syscallent stubs cannot be generated.
configure: add --disable-mpers and --enable-mpers=check options
On architectures supporting multiple personalities, multiple
personalities support in strace is required for proper decoding of
structures used by tracees with personalities that differ from the
personality of strace.
New configure options control whether multiple personalities support
in strace is mandatory, optional, or disabled.
The default is changed from what is now equivalent of
--enable-mpers=check (automatically detect whether required mpers
support could be enabled) to --enable-mpers (terminate the build
if required mpers support could not be enabled).
* configure.ac (AC_ARG_ENABLE([mpers])): New option.
* m4/mpers.m4 (st_MPERS): Use enable_mpers. Terminate the build
if mpers could not be enabled and enable_mpers==yes.
* strace.spec.in: Specify --enable-mpers=check to %configure.
* debian/rules (build/Makefile, build64/Makefile): Specify
--enable-mpers=check to configure.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org> Suggested-by: DJ Delorie <dj@redhat.com>
Issue a warning when strace lacks tracee personality support
* defs.h (HAVE_PERSONALITY_1_MPERS, HAVE_PERSONALITY_2_MPERS): New
macros.
* syscall.c (update_personality): Add need_mpers_warning array
initialized with mpers support data. Use it for printing the mpers
unavailability warning once per personality.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
Search for <libiberty/demangle.h> in addition to <demangle.h>
This is the location where this header is installed on Debian-based
systems.
* configure.ac: Check for libiberty/demangle.h in addition to
demangle.h.
* unwind.c [USE_DEMANGLE]: Include either <demangle.h> or
<libiberty_demangle.h> based on the presence of HAVE_DEMANGLE_H and
HAVE_LIBIBERTY_DEMANGLE_H macros.
Provide strace's native arch to the test framework
* configure.ac (arch_native): New variable, set to arch.
* tests/Makefile.am (NATIVE_ARCH): New variable, set to @arch_native@.
(AM_TEST_LOG_FLAGS): Pass NATIVE_ARCH as STRACE_NATIVE_ARCH environment
variable.
tests: check decoding of modify_ldt with for 4-byte-available user_desc
Since there is possibility now that strace read only entry_number field
of the user_desc struct, let's check that it doesn't do it with
modify_ldt syscall.
* tests/modify_ldt.c (main): Add 4-byte-sized tail_alloc'ed variable.
Try to provide it as an argument to modify_ldt.
Allow separate printing of struct user_desc.entry_number
Kernel reads only entry_number field in the beginning of the
get_thread_area syscall handler. Let's replicate this behaviour.
* defs.h (enum user_desc_print_filter): New enumeration.
(print_user_desc): Add an argument for signalling which part of the
structure should be printed.
* clone.c (print_tls_arg): Update print_user_desc call.
* ldt.c (print_user_desc): Add filter argument. Print entry_number on
entering and the rest on exiting. Store entering value of the
entry_number field in order to print the updated value in the impossible
case of changed entry_number value.
(SYS_FUNC(modify_ldt), SYS_FUNC(set_thread_area)): Update
print_user_desc call.
(SYS_FUNC(get_thread_area)): Call print_user_desc with
USER_DESC_ENTERING format argument on entering and with
USER_DESC_EXITING on exiting.
* ldt.c (modify_ldt): Move parsing under entering(tcp). Check whether
return code is erroneous and set tcp->u_error appropriately along with
RVAL_PRINT_ERR_VAL flag.
syscall.c: add support for printing return value and error code
Some weird syscalls (like modify_ldt) return value that doesn't indicate
an error (less than -4096), but it is, in fact, erroneous (because they
decide to clip the return value to 32-bit, for example).
Add a flag to print decoded error code along with syscall return value.
* defs.h (RVAL_PRINT_ERR_VAL): New rval flag.
* syscall.c (syscall_exiting_trace): Handle it.
ldt.c: make struct user_desc output more structured
Also, while we are here, let's fix print qualifiers (which should be %u
and not %d).
* ldt.c (print_user_desc): Use PRINT_FIELD_* macros for printing
structure.
(SYS_FUNC(set_thread_area)): Change field key-value separator from ":"
to "=", change print format qualifier from %d to %u.
Add a macro for printing fields explicitly casted to specific type.
This is useful for bit fields, as otherwise the magic of *_extend_to_*
macros breaks.
print_fields.h: rename PRINT_FIELD_UID to PRINT_FIELD_ID
As uid is not the only thing that has a special treatment of the -1
value (and, as a result, needs special care), let's rename
PRINT_FIELD_UID to PRINT_FIELD_ID and make PRINT_FIELD_UID its alias.
* print_fields.h (PRINT_FIELD_ID): Rename from PRINT_FIELD_UID.
(PRINT_FIELD_UID): Define to PRINT_FIELD_ID.
* count.c (call_summary_pers): Change the type of sorted_count
to "unsigned int *". Replace sizeof(int) with sizeof(sorted_count[0]).
Change the type of idx to unsigned int.
Pass tcp argument to get_optmem_max/read_int_from_file
In preparation to passing tcp to all tracee-related syscalls.
* defs.h (read_int_from_file): Add "struct tcb *" as the first argument.
* util.c (read_int_from_file): Likewise.
* msghdr.c (get_optmem_max): Add "struct tcb *tcp" as the first
argument, pass it to read_int_from_file call.
(decode_msg_control): Pass tcp to get_optmem_max.
Since set_sigaction() actually specifies sa_handler and not sa_sigaction,
rename set_sigaction() to set_sighandler() for future definition of
set_sigaction() function as specifying sa_sigaction.
* strace.c (set_sigaction): Rename to set_sighandler.
All callers updated.