From 787f85bae4ca460c33896599da176cc529bafaba Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Tue, 4 Apr 2023 22:06:18 +0200 Subject: Implement an ability to filter syscalls that operate on specific FDs Introduce -e trace-fds= qualifier that allows specifying a set of FDs of interest, operations on which are to be traced. Works in conjunction (or, more specifically, inclusive disjunction) with the path tracing functionality. * src/defs.h: Include "number_set.h". (tracing_fds): New external variable. (pathtrace_match_set): Add new fdset argument to the declaration. (pathtrace_match): Pass trace_fd_set in the new argument to the pathtrace_match_set call. (qualify_trace_fd): New function declaration. * src/filter_qualify.c (trace_fd_set): New variable. (qualify_trace_fd): New function. (qual_options): Add various FD tracing-related items. * src/number_set.h (trace_fd_set): New external variable declaration. * src/pathtrace.c (pathmatch, upathmatch): Bail out if set is NULL. (fdmatch): Add fdset argument, check fd for non-negativity and presence in fdset if fdset is non-NULL. (match_xselect_args): Add fdset argument, pass it to the fdmatch call. (pathtrace_match_set): Add fdset argument, pass it to fdmatch and match_xselect_args calls. * src/syscall.c (syscall_entering_trace): Check tracing_fds in addition to tracing_paths as a predicate for performing pathtrace_match check. * src/strace.c (tracing_fds): New variable. (init) : New enum item. (init) : Add"trace-fds" option. (init) : Call qualify_trace_fd. (usage): Document -e trace-fds. * doc/strace.1.in: Likewise. * tests/.gitignore: Add dup-trace-fds-0, dup-trace-fds-0-9, dup-trace-fds-0-P, dup-trace-fds-not-9, dup2-e-fd-0, dup2-e-fd-0-9, dup2-e-fd-0-P, dup2-e-fd-not-9, ppoll-e-trace-fds-23, ppoll-e-trace-fds-23-42, ppoll-e-trace-fds-not-9-42-P, select-trace-fd-7, select-trace-fd-7-9, and select-trace-fd-7-P. * tests/Makefile.am (check_PROGRAMS): Add ppoll-e-trace-fds-23, ppoll-e-trace-fds-23-42, ppoll-e-trace-fds-not-9-42-P, select-trace-fd-7, select-trace-fd-7-9, and select-trace-fd-7-P. * tests/dup-P.c (PATH_TRACING): Set to 1. * tests/dup2-P.c (PATH_TRACING): Likewise. * tests/dup.c: Accommodate test for checking tracing-fds functionality. * tests/dup2.c: Likewise. * tests/ppoll.c: Likewise. * tests/xselect.c: Likewise. * tests/gen_tests.in (dup-trace-fds-0, dup-trace-fds-0-9, dup-trace-fds-0-P, dup-trace-fds-not-9, dup2-e-fd-0, dup2-e-fd-0-9, dup2-e-fd-0-P, dup2-e-fd-not-9, ppoll-e-trace-fds-23, ppoll-e-trace-fds-23-42, ppoll-e-trace-fds-not-9-42-P, select-trace-fd-7, select-trace-fd-7-9, select-trace-fd-7-P): New tests. * tests/options-syntax.test: Add trace-fds-related option syntax checks. * tests/pure_executables.list: Add dup-trace-fds-0, dup-trace-fds-0-9, dup-trace-fds-0-P, dup-trace-fds-not-9, dup2-e-fd-0, dup2-e-fd-0-9, dup2-e-fd-0-P, and dup2-e-fd-not-9. * tests/dup-trace-fds-0-9.c: New file. * tests/dup-trace-fds-0-P.c: Likewise. * tests/dup-trace-fds-0.c: Likewise. * tests/dup-trace-fds-not-9.c: Likewise. * tests/dup2-e-fd-0-9.c: Likewise. * tests/dup2-e-fd-0-P.c: Likewise. * tests/dup2-e-fd-0.c: Likewise. * tests/dup2-e-fd-not-9.c: Likewise. * tests/ppoll-e-trace-fds-23-42.c: Likewise. * tests/ppoll-e-trace-fds-23.c: Likewise. * tests/ppoll-e-trace-fds-not-9-42-P.c: Likewise. * tests/select-trace-fd-7-9.c: Likewise. * tests/select-trace-fd-7-P.c: Likewise. * tests/select-trace-fd-7.c: Likewise. * NEWS: Mention it. Suggested-by: Marty Leisner Link: https://lists.strace.io/pipermail/strace-devel/2023-March/011209.html --- NEWS | 2 + doc/strace.1.in | 17 ++++ src/defs.h | 8 +- src/filter_qualify.c | 14 ++++ src/number_set.h | 1 + src/pathtrace.c | 58 ++++++++------ src/strace.c | 8 ++ src/syscall.c | 3 +- tests/.gitignore | 14 ++++ tests/Makefile.am | 6 ++ tests/dup-P.c | 2 +- tests/dup-trace-fds-0-9.c | 4 + tests/dup-trace-fds-0-P.c | 4 + tests/dup-trace-fds-0.c | 3 + tests/dup-trace-fds-not-9.c | 4 + tests/dup.c | 29 ++++++- tests/dup2-P.c | 2 +- tests/dup2-e-fd-0-9.c | 4 + tests/dup2-e-fd-0-P.c | 5 ++ tests/dup2-e-fd-0.c | 3 + tests/dup2-e-fd-not-9.c | 4 + tests/dup2.c | 59 ++++++++++++-- tests/gen_tests.in | 20 ++++- tests/options-syntax.test | 7 ++ tests/ppoll-e-trace-fds-23-42.c | 4 + tests/ppoll-e-trace-fds-23.c | 3 + tests/ppoll-e-trace-fds-not-9-42-P.c | 7 ++ tests/ppoll.c | 92 ++++++++++++++++++--- tests/pure_executables.list | 8 ++ tests/select-trace-fd-7-9.c | 3 + tests/select-trace-fd-7-P.c | 3 + tests/select-trace-fd-7.c | 2 + tests/xselect.c | 151 ++++++++++++++++++++++------------- 33 files changed, 448 insertions(+), 106 deletions(-) create mode 100644 tests/dup-trace-fds-0-9.c create mode 100644 tests/dup-trace-fds-0-P.c create mode 100644 tests/dup-trace-fds-0.c create mode 100644 tests/dup-trace-fds-not-9.c create mode 100644 tests/dup2-e-fd-0-9.c create mode 100644 tests/dup2-e-fd-0-P.c create mode 100644 tests/dup2-e-fd-0.c create mode 100644 tests/dup2-e-fd-not-9.c create mode 100644 tests/ppoll-e-trace-fds-23-42.c create mode 100644 tests/ppoll-e-trace-fds-23.c create mode 100644 tests/ppoll-e-trace-fds-not-9-42-P.c create mode 100644 tests/select-trace-fd-7-9.c create mode 100644 tests/select-trace-fd-7-P.c create mode 100644 tests/select-trace-fd-7.c diff --git a/NEWS b/NEWS index 5bf6c80cb..e553e094c 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ Noteworthy changes in release ?.? (????-??-??) ============================================== * Improvements + * Implemented -e trace-fds=set option for filtering only the syscalls + that operate on the specified set of file descriptors. * Updated lists of ioctl commands from Linux 6.3. Noteworthy changes in release 6.2 (2023-02-26) diff --git a/doc/strace.1.in b/doc/strace.1.in index 71661bd2e..25d87bf37 100644 --- a/doc/strace.1.in +++ b/doc/strace.1.in @@ -249,6 +249,7 @@ where .I qualifier is one of .BR trace " (or " t ), +.BR trace\-fds " (or " trace\-fd " or " fd " or " fds ), .BR abbrev " (or " a ), .BR verbose " (or " v ), .BR raw " (or " x ), @@ -645,6 +646,21 @@ about the user/kernel boundary if only a subset of system calls are being monitored. The default is .BR trace = all . .TP +\fB\-e\ trace\-fd\fR=\,\fIset\fR +.TQ +\fB\-e\ trace\-fds\fR=\,\fIset\fR +.TQ +\fB\-e\ fd\fR=\,\fIset\fR +.TQ +\fB\-e\ fds\fR=\,\fIset\fR +.TQ +\fB\-\-trace\-fds\fR=\,\fIset\fR +Trace only the syscalls that operate +on the specified subset of (non-negative) file descriptors. +Note that usage of this option also filters out all the syscalls +that do not operate on file descriptors at all. +Applies in (inclusive) disjunction with the \fB\-\-trace\-path\fR option. +.TP \fB\-e\ signal\fR=\,\fIset\fR .TQ \fB\-e\ signals\fR=\,\fIset\fR @@ -725,6 +741,7 @@ Trace only system calls accessing Multiple .B \-P options can be used to specify several paths. +Applies in (inclusive) disjunction with the \fB\-\-trace\-fds\fR option. .TP .B \-z .TQ diff --git a/src/defs.h b/src/defs.h index 6c93d8460..3348c1e17 100644 --- a/src/defs.h +++ b/src/defs.h @@ -40,6 +40,7 @@ # include "list.h" # include "macros.h" # include "mpers_type.h" +# include "number_set.h" # include "string_to_uint.h" # include "sysent.h" # include "xmalloc.h" @@ -513,6 +514,7 @@ extern int Tflag_scale; extern int Tflag_width; extern bool iflag; extern bool count_wallclock; +extern bool tracing_fds; struct path_set_item { const char *path; @@ -798,7 +800,8 @@ extern const char *signame(const int); extern const char *sprintsigname(const int); extern void pathtrace_select_set(const char *, struct path_set *); -extern bool pathtrace_match_set(struct tcb *, struct path_set *); +extern bool pathtrace_match_set(struct tcb *, struct path_set *, + struct number_set *); static inline void pathtrace_select(const char *path) @@ -809,7 +812,7 @@ pathtrace_select(const char *path) static inline bool pathtrace_match(struct tcb *tcp) { - return pathtrace_match_set(tcp, &global_path_set); + return pathtrace_match_set(tcp, &global_path_set, trace_fd_set); } /** @@ -1401,6 +1404,7 @@ extern void print_affinitylist(struct tcb *const tcp, const kernel_ulong_t addr, extern void qualify(const char *); extern void qualify_trace(const char *); +extern void qualify_trace_fd(const char *); extern void qualify_abbrev(const char *); extern void qualify_verbose(const char *); extern void qualify_raw(const char *); diff --git a/src/filter_qualify.c b/src/filter_qualify.c index c3bf2e9ad..3aa9f2a19 100644 --- a/src/filter_qualify.c +++ b/src/filter_qualify.c @@ -24,6 +24,7 @@ struct number_set *quiet_set; struct number_set *decode_fd_set; struct number_set *decode_pid_set; struct number_set *trace_set; +struct number_set *trace_fd_set; bool quiet_set_updated = false; bool decode_fd_set_updated = false; @@ -495,6 +496,15 @@ qualify_trace(const char *const str) qualify_syscall_tokens(str, trace_set); } +void +qualify_trace_fd(const char *const str) +{ + if (!trace_fd_set) + trace_fd_set = alloc_number_set_array(1); + qualify_tokens(str, trace_fd_set, string_to_uint, "descriptor"); + tracing_fds = true; +} + void qualify_abbrev(const char *const str) { @@ -655,6 +665,10 @@ static const struct qual_options { } qual_options[] = { { "trace", qualify_trace }, { "t", qualify_trace }, + { "trace-fd", qualify_trace_fd }, + { "trace-fds", qualify_trace_fd }, + { "fd", qualify_trace_fd }, + { "fds", qualify_trace_fd }, { "abbrev", qualify_abbrev }, { "a", qualify_abbrev }, { "verbose", qualify_verbose }, diff --git a/src/number_set.h b/src/number_set.h index 5cd030f7c..639d4c256 100644 --- a/src/number_set.h +++ b/src/number_set.h @@ -98,5 +98,6 @@ extern struct number_set *quiet_set; extern struct number_set *decode_fd_set; extern struct number_set *decode_pid_set; extern struct number_set *trace_set; +extern struct number_set *trace_fd_set; #endif /* !STRACE_NUMBER_SET_H */ diff --git a/src/pathtrace.c b/src/pathtrace.c index f94f2e60d..3a97f4557 100644 --- a/src/pathtrace.c +++ b/src/pathtrace.c @@ -27,6 +27,9 @@ struct path_set global_path_set; static bool pathmatch(const char *path, struct path_set *set) { + if (!set) + return false; + for (unsigned int i = 0; i < set->num_selected; ++i) { if (strcmp(path, set->paths_selected[i].path) == 0) return true; @@ -41,6 +44,9 @@ static bool upathmatch(struct tcb *const tcp, const kernel_ulong_t upath, struct path_set *set) { + if (!set) + return false; + char path[PATH_MAX + 1]; return umovestr(tcp, upath, sizeof(path), path) > 0 && @@ -51,8 +57,13 @@ upathmatch(struct tcb *const tcp, const kernel_ulong_t upath, * Return true if specified fd maps to a path we're tracing. */ static bool -fdmatch(struct tcb *tcp, int fd, struct path_set *set) +fdmatch(struct tcb *tcp, int fd, struct path_set *set, struct number_set *fdset) { + if (fdset && fd >= 0 && is_number_in_set(fd, fdset)) + return true; + if (!set) + return false; + char path[PATH_MAX + 1]; int n = getfdpath(tcp, fd, path, sizeof(path)); @@ -194,7 +205,7 @@ pathtrace_select_set(const char *path, struct path_set *set) static bool match_xselect_args(struct tcb *tcp, const kernel_ulong_t *args, - struct path_set *set) + struct path_set *set, struct number_set *fdset) { /* Kernel truncates arg[0] to int, we do the same. */ int nfds = (int) args[0]; @@ -216,7 +227,7 @@ match_xselect_args(struct tcb *tcp, const kernel_ulong_t *args, j = next_set_bit(fds, j, nfds); if (j < 0) break; - if (fdmatch(tcp, j, set)) { + if (fdmatch(tcp, j, set, fdset)) { free(fds); return true; } @@ -232,7 +243,8 @@ match_xselect_args(struct tcb *tcp, const kernel_ulong_t *args, * (or if no paths have been specified for tracing). */ bool -pathtrace_match_set(struct tcb *tcp, struct path_set *set) +pathtrace_match_set(struct tcb *tcp, struct path_set *set, + struct number_set *fdset) { const struct_sysent *s; @@ -254,8 +266,8 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) case SEN_sendfile64: case SEN_tee: /* fd, fd */ - return fdmatch(tcp, tcp->u_arg[0], set) || - fdmatch(tcp, tcp->u_arg[1], set); + return fdmatch(tcp, tcp->u_arg[0], set, fdset) || + fdmatch(tcp, tcp->u_arg[1], set, fdset); case SEN_execveat: case SEN_faccessat: @@ -280,7 +292,7 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) case SEN_utimensat_time32: case SEN_utimensat_time64: /* fd, path */ - return fdmatch(tcp, tcp->u_arg[0], set) || + return fdmatch(tcp, tcp->u_arg[0], set, fdset) || upathmatch(tcp, tcp->u_arg[1], set); case SEN_link: @@ -300,8 +312,8 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) case SEN_renameat2: case SEN_renameat: /* fd, path, fd, path */ - return fdmatch(tcp, tcp->u_arg[0], set) || - fdmatch(tcp, tcp->u_arg[2], set) || + return fdmatch(tcp, tcp->u_arg[0], set, fdset) || + fdmatch(tcp, tcp->u_arg[2], set, fdset) || upathmatch(tcp, tcp->u_arg[1], set) || upathmatch(tcp, tcp->u_arg[3], set); @@ -314,7 +326,7 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) kernel_ulong_t *args = fetch_indirect_syscall_args(tcp, tcp->u_arg[0], 6); - return args && fdmatch(tcp, args[4], set); + return args && fdmatch(tcp, args[4], set, fdset); } #endif /* HAVE_ARCH_OLD_MMAP */ @@ -323,22 +335,22 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) case SEN_mmap_pgoff: case SEN_ARCH_mmap: /* x, x, x, x, fd */ - return fdmatch(tcp, tcp->u_arg[4], set); + return fdmatch(tcp, tcp->u_arg[4], set, fdset); case SEN_symlinkat: /* x, fd, path */ - return fdmatch(tcp, tcp->u_arg[1], set) || + return fdmatch(tcp, tcp->u_arg[1], set, fdset) || upathmatch(tcp, tcp->u_arg[2], set); case SEN_copy_file_range: case SEN_splice: /* fd, x, fd, x, x, x */ - return fdmatch(tcp, tcp->u_arg[0], set) || - fdmatch(tcp, tcp->u_arg[2], set); + return fdmatch(tcp, tcp->u_arg[0], set, fdset) || + fdmatch(tcp, tcp->u_arg[2], set, fdset); case SEN_epoll_ctl: /* x, x, fd, x */ - return fdmatch(tcp, tcp->u_arg[2], set); + return fdmatch(tcp, tcp->u_arg[2], set, fdset); case SEN_fanotify_mark: @@ -346,7 +358,7 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) /* x, x, mask (64 bit), fd, path */ unsigned long long mask = 0; unsigned int argn = getllval(tcp, &mask, 2); - return fdmatch(tcp, tcp->u_arg[argn], set) || + return fdmatch(tcp, tcp->u_arg[argn], set, fdset) || upathmatch(tcp, tcp->u_arg[argn + 1], set); } #if HAVE_ARCH_OLD_SELECT @@ -355,13 +367,13 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) kernel_ulong_t *args = fetch_indirect_syscall_args(tcp, tcp->u_arg[0], 5); - return args && match_xselect_args(tcp, args, set); + return args && match_xselect_args(tcp, args, set, fdset); } #endif case SEN_pselect6_time32: case SEN_pselect6_time64: case SEN_select: - return match_xselect_args(tcp, tcp->u_arg, set); + return match_xselect_args(tcp, tcp->u_arg, set, fdset); case SEN_poll_time32: case SEN_poll_time64: case SEN_ppoll_time32: @@ -381,7 +393,7 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) for (kernel_ulong_t cur = start; cur < end; cur += sizeof(fds)) { if (umove(tcp, cur, &fds)) break; - if (fdmatch(tcp, fds.fd, set)) + if (fdmatch(tcp, fds.fd, set, fdset)) return true; } @@ -394,10 +406,10 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) switch (cmd) { case 3 /* FSCONFIG_SET_PATH */: case 4 /* FSCONFIG_SET_PATH_EMPTY */: - return fdmatch(tcp, tcp->u_arg[4], set) || - upathmatch(tcp, tcp->u_arg[3], set); + return fdmatch(tcp, tcp->u_arg[4], set, fdset) + || upathmatch(tcp, tcp->u_arg[3], set); case 5 /* FSCONFIG_SET_FD */: - return fdmatch(tcp, tcp->u_arg[4], set); + return fdmatch(tcp, tcp->u_arg[4], set, fdset); } return false; @@ -461,7 +473,7 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) return upathmatch(tcp, tcp->u_arg[0], set); if (s->sys_flags & (TRACE_DESC | TRACE_NETWORK)) - return fdmatch(tcp, tcp->u_arg[0], set); + return fdmatch(tcp, tcp->u_arg[0], set, fdset); return false; } diff --git a/src/strace.c b/src/strace.c index 7a58bdbd6..a2022d273 100644 --- a/src/strace.c +++ b/src/strace.c @@ -84,6 +84,7 @@ int Tflag_scale = 1000; int Tflag_width = 6; bool iflag; bool count_wallclock; +bool tracing_fds; static bool nflag; static int tflag_scale = 1000000000; static unsigned tflag_width = 0; @@ -335,6 +336,8 @@ Filtering:\n\ -e status=SET, --status=SET\n\ print only system calls with the return statuses in SET\n\ statuses: successful, failed, unfinished, unavailable, detached\n\ + -e trace-fds=SET, --trace-fds=SET\n\ + trace operations on file descriptors from SET\n\ -P PATH, --trace-path=PATH\n\ trace accesses to PATH\n\ -z, --successful-only\n\ @@ -2258,6 +2261,7 @@ init(int argc, char *argv[]) GETOPT_TIPS, GETOPT_QUAL_TRACE, + GETOPT_QUAL_TRACE_FD, GETOPT_QUAL_ABBREV, GETOPT_QUAL_VERBOSE, GETOPT_QUAL_RAW, @@ -2317,6 +2321,7 @@ init(int argc, char *argv[]) { "tips", optional_argument, 0, GETOPT_TIPS }, { "trace", required_argument, 0, GETOPT_QUAL_TRACE }, + { "trace-fds", required_argument, 0, GETOPT_QUAL_TRACE_FD }, { "abbrev", required_argument, 0, GETOPT_QUAL_ABBREV }, { "verbose", required_argument, 0, GETOPT_QUAL_VERBOSE }, { "raw", required_argument, 0, GETOPT_QUAL_RAW }, @@ -2552,6 +2557,9 @@ init(int argc, char *argv[]) case GETOPT_QUAL_TRACE: qualify_trace(optarg); break; + case GETOPT_QUAL_TRACE_FD: + qualify_trace_fd(optarg); + break; case GETOPT_QUAL_ABBREV: qualify_abbrev(optarg); break; diff --git a/src/syscall.c b/src/syscall.c index cc37aa30c..083b122d1 100644 --- a/src/syscall.c +++ b/src/syscall.c @@ -646,7 +646,8 @@ syscall_entering_trace(struct tcb *tcp, unsigned int *sig) } } - if (hide_log(tcp) || !traced(tcp) || (tracing_paths && !pathtrace_match(tcp))) { + if (hide_log(tcp) || !traced(tcp) + || ((tracing_paths || tracing_fds) && !pathtrace_match(tcp))) { tcp->flags |= TCB_FILTERED; return 0; } diff --git a/tests/.gitignore b/tests/.gitignore index 5935c39d9..1baeb5896 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -95,10 +95,18 @@ dev--decode-fds-socket dev-yy dup dup-P +dup-trace-fds-0 +dup-trace-fds-0-9 +dup-trace-fds-0-P +dup-trace-fds-not-9 dup-y dup-yy dup2 dup2-P +dup2-e-fd-0 +dup2-e-fd-0-9 +dup2-e-fd-0-P +dup2-e-fd-not-9 dup2-y dup2-yy dup3 @@ -699,6 +707,9 @@ poll poll-P ppoll ppoll-P +ppoll-e-trace-fds-23 +ppoll-e-trace-fds-23-42 +ppoll-e-trace-fds-not-9-42-P ppoll-v prctl-arg2-intptr prctl-cap-ambient @@ -908,6 +919,9 @@ segv_accerr segv_pkuerr select select-P +select-trace-fd-7 +select-trace-fd-7-9 +select-trace-fd-7-P semop semop-indirect semtimedop diff --git a/tests/Makefile.am b/tests/Makefile.am index 70153a5b1..66f6bda7b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -280,6 +280,9 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \ pidns-cache \ poll-P \ ppoll-P \ + ppoll-e-trace-fds-23 \ + ppoll-e-trace-fds-23-42 \ + ppoll-e-trace-fds-not-9-42-P \ ppoll-v \ prctl-fp-mode \ prctl-pac-enabled-keys-success \ @@ -359,6 +362,9 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \ segv_accerr \ segv_pkuerr \ select-P \ + select-trace-fd-7 \ + select-trace-fd-7-9 \ + select-trace-fd-7-P \ set_ptracer_any \ set_sigblock \ set_sigign \ diff --git a/tests/dup-P.c b/tests/dup-P.c index c65def8fd..695c4a7b0 100644 --- a/tests/dup-P.c +++ b/tests/dup-P.c @@ -1,4 +1,4 @@ -#define PATH_TRACING +#define PATH_TRACING 1 #define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/") #include "dup.c" diff --git a/tests/dup-trace-fds-0-9.c b/tests/dup-trace-fds-0-9.c new file mode 100644 index 000000000..760cbf804 --- /dev/null +++ b/tests/dup-trace-fds-0-9.c @@ -0,0 +1,4 @@ +#define TRACE_FDS 1 +#define TRACE_FD_0 1 +#define TRACE_FD_9 1 +#include "dup.c" diff --git a/tests/dup-trace-fds-0-P.c b/tests/dup-trace-fds-0-P.c new file mode 100644 index 000000000..89c8d87ec --- /dev/null +++ b/tests/dup-trace-fds-0-P.c @@ -0,0 +1,4 @@ +#define PATH_TRACING 1 +#define TRACE_FDS 1 +#define TRACE_FD_0 1 +#include "dup.c" diff --git a/tests/dup-trace-fds-0.c b/tests/dup-trace-fds-0.c new file mode 100644 index 000000000..f08c22b0b --- /dev/null +++ b/tests/dup-trace-fds-0.c @@ -0,0 +1,3 @@ +#define TRACE_FDS 1 +#define TRACE_FD_0 1 +#include "dup.c" diff --git a/tests/dup-trace-fds-not-9.c b/tests/dup-trace-fds-not-9.c new file mode 100644 index 000000000..143c3cc12 --- /dev/null +++ b/tests/dup-trace-fds-not-9.c @@ -0,0 +1,4 @@ +#define TRACE_FDS 1 +#define TRACE_FD_0 1 +#define TRACE_OTHER_FDS 1 +#include "dup.c" diff --git a/tests/dup.c b/tests/dup.c index df0251f9d..7b34c59a3 100644 --- a/tests/dup.c +++ b/tests/dup.c @@ -23,6 +23,22 @@ # define SKIP_IF_PROC_IS_UNAVAILABLE #endif +#ifndef TRACE_FDS +# define TRACE_FDS 0 +#endif +#ifndef PATH_TRACING +# define PATH_TRACING 0 +#endif +#ifndef TRACE_FD_0 +# define TRACE_FD_0 (!TRACE_FDS && !PATH_TRACING) +#endif +#ifndef TRACE_OTHER_FDS +# define TRACE_OTHER_FDS (!TRACE_FDS && !PATH_TRACING) +#endif +#ifndef TRACE_FD_9 +# define TRACE_FD_9 (!TRACE_FDS && !PATH_TRACING) +#endif + static const char *errstr; static long @@ -42,22 +58,29 @@ main(void) SKIP_IF_PROC_IS_UNAVAILABLE; k_dup(-1); -#ifndef PATH_TRACING +#if !PATH_TRACING && !TRACE_FDS printf("dup(-1) = %s\n", errstr); #endif int d1 = k_dup(0); -#ifndef PATH_TRACING +#if !!TRACE_FD_0 printf("dup(0" FD0_PATH ") = %d" FD0_PATH "\n", d1); #endif int d2 = k_dup(d1); -#ifndef PATH_TRACING +#if !!TRACE_OTHER_FDS printf("dup(%d" FD0_PATH ") = %d" FD0_PATH "\n", d1, d2); #endif d2 = k_dup(9); +#if PATH_TRACING || !!TRACE_FD_9 printf("dup(9" FD9_PATH ") = %d" FD9_PATH "\n", d2); +#endif + + d1 = k_dup(d2); +#if PATH_TRACING || !!TRACE_OTHER_FDS + printf("dup(%d" FD9_PATH ") = %d" FD9_PATH "\n", d2, d1); +#endif puts("+++ exited with 0 +++"); return 0; diff --git a/tests/dup2-P.c b/tests/dup2-P.c index f9603eabd..59af39227 100644 --- a/tests/dup2-P.c +++ b/tests/dup2-P.c @@ -1,4 +1,4 @@ -#define PATH_TRACING +#define PATH_TRACING 1 #define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/") #include "dup2.c" diff --git a/tests/dup2-e-fd-0-9.c b/tests/dup2-e-fd-0-9.c new file mode 100644 index 000000000..7367af64b --- /dev/null +++ b/tests/dup2-e-fd-0-9.c @@ -0,0 +1,4 @@ +#define TRACE_FDS 1 +#define TRACE_FD_0 1 +#define TRACE_FD_9 1 +#include "dup2.c" diff --git a/tests/dup2-e-fd-0-P.c b/tests/dup2-e-fd-0-P.c new file mode 100644 index 000000000..a97f2d4ca --- /dev/null +++ b/tests/dup2-e-fd-0-P.c @@ -0,0 +1,5 @@ +#define TRACE_FDS 1 +#define TRACE_FD_0 1 +#define TRACE_FD_9 1 +#define PATH_TRACING 1 +#include "dup2.c" diff --git a/tests/dup2-e-fd-0.c b/tests/dup2-e-fd-0.c new file mode 100644 index 000000000..b42e04d39 --- /dev/null +++ b/tests/dup2-e-fd-0.c @@ -0,0 +1,3 @@ +#define TRACE_FDS 1 +#define TRACE_FD_0 1 +#include "dup2.c" diff --git a/tests/dup2-e-fd-not-9.c b/tests/dup2-e-fd-not-9.c new file mode 100644 index 000000000..5bd2ab549 --- /dev/null +++ b/tests/dup2-e-fd-not-9.c @@ -0,0 +1,4 @@ +#define TRACE_FDS 1 +#define TRACE_FD_0 1 +#define TRACE_OTHER_FDS 1 +#include "dup2.c" diff --git a/tests/dup2.c b/tests/dup2.c index ec735e928..96b155b85 100644 --- a/tests/dup2.c +++ b/tests/dup2.c @@ -25,6 +25,23 @@ # define SKIP_IF_PROC_IS_UNAVAILABLE # endif +# ifndef PATH_TRACING +# define PATH_TRACING 0 +# endif +# ifndef TRACE_FDS +# define TRACE_FDS 0 +# endif +# ifndef TRACE_FD_0 +# define TRACE_FD_0 (!TRACE_FDS && !PATH_TRACING) +# endif +# ifndef TRACE_OTHER_FDS +# define TRACE_OTHER_FDS (!TRACE_FDS && !PATH_TRACING) +# endif +# ifndef TRACE_FD_9 +# define TRACE_FD_9 (!TRACE_FDS && !PATH_TRACING) +# endif + + static const char *errstr; static long @@ -49,69 +66,95 @@ main(void) if (k_dup2(0, 0)) perror_msg_and_skip("dup2"); -# ifndef PATH_TRACING +# if TRACE_FD_0 printf("dup2(0" FD0_PATH ", 0" FD0_PATH ") = 0" FD0_PATH "\n"); # endif k_dup2(-1, -2); -# ifndef PATH_TRACING +# if !PATH_TRACING && !TRACE_FDS printf("dup2(-1, -2) = %s\n", errstr); # endif k_dup2(-2, -1); -# ifndef PATH_TRACING +# if !PATH_TRACING && !TRACE_FDS printf("dup2(-2, -1) = %s\n", errstr); # endif k_dup2(-3, 0); -# ifndef PATH_TRACING +# if TRACE_FD_0 printf("dup2(-3, 0" FD0_PATH ") = %s\n", errstr); # endif k_dup2(0, -4); -# ifndef PATH_TRACING +# if TRACE_FD_0 printf("dup2(0" FD0_PATH ", -4) = %s\n", errstr); # endif k_dup2(-5, 9); +# if PATH_TRACING || TRACE_FD_9 printf("dup2(-5, 9" FD9_PATH ") = %s\n", errstr); +# endif k_dup2(9, -6); +# if PATH_TRACING || TRACE_FD_9 printf("dup2(9" FD9_PATH ", -6) = %s\n", errstr); +# endif k_dup2(9, 9); +# if PATH_TRACING || TRACE_FD_9 printf("dup2(9" FD9_PATH ", 9" FD9_PATH ") = 9" FD9_PATH "\n"); +# endif k_dup2(0, fd0); -# ifndef PATH_TRACING +# if TRACE_FD_0 printf("dup2(0" FD0_PATH ", %d" FD0_PATH ") = %d" FD0_PATH "\n", fd0, fd0); # endif + k_dup2(fd0, fd9); +# if PATH_TRACING || TRACE_OTHER_FDS + printf("dup2(%d" FD0_PATH ", %d" FD9_PATH ") = %d" FD0_PATH "\n", + fd0, fd9, fd9); +# endif + + k_dup2(fd0, fd9); +# if TRACE_OTHER_FDS + printf("dup2(%d" FD0_PATH ", %d" FD0_PATH ") = %d" FD0_PATH "\n", + fd0, fd9, fd9); +# endif + k_dup2(9, fd9); - printf("dup2(9" FD9_PATH ", %d" FD9_PATH ") = %d" FD9_PATH "\n", +# if PATH_TRACING || TRACE_FD_9 || TRACE_OTHER_FDS + printf("dup2(9" FD9_PATH ", %d" FD0_PATH ") = %d" FD9_PATH "\n", fd9, fd9); +# endif k_dup2(0, fd9); +# if PATH_TRACING || TRACE_FD_0 printf("dup2(0" FD0_PATH ", %d" FD9_PATH ") = %d" FD0_PATH "\n", fd9, fd9); +# endif k_dup2(9, fd0); +# if PATH_TRACING || TRACE_FD_9 || TRACE_OTHER_FDS printf("dup2(9" FD9_PATH ", %d" FD0_PATH ") = %d" FD9_PATH "\n", fd0, fd0); +# endif close(fd0); close(fd9); k_dup2(0, fd0); -# ifndef PATH_TRACING +# if TRACE_FD_0 printf("dup2(0" FD0_PATH ", %d) = %d" FD0_PATH "\n", fd0, fd0); # endif k_dup2(9, fd9); +# if PATH_TRACING || TRACE_FD_9 || TRACE_OTHER_FDS printf("dup2(9" FD9_PATH ", %d) = %d" FD9_PATH "\n", fd9, fd9); +# endif puts("+++ exited with 0 +++"); return 0; diff --git a/tests/gen_tests.in b/tests/gen_tests.in index eceac8d60..508de29ca 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -81,10 +81,18 @@ dev--decode-fds-socket -a9 -e trace=openat,fsync -P "/dev/full" -P "/dev/zero" - dev-yy -a30 -e trace=openat,fsync -P "/dev/full" -P "/dev/zero" -P "/dev/sda" -yy dup -a7 9>>/dev/full dup-P -a7 --trace=dup -P /dev/full 9>>/dev/full +dup-trace-fds-0 -a7 --trace=dup --trace-fds=0 9>>/dev/full +dup-trace-fds-0-9 -a7 --trace=dup --trace-fds=0,9 9>>/dev/full +dup-trace-fds-0-P -a7 --trace=dup --trace-fds=0 -P /dev/full 9>>/dev/full +dup-trace-fds-not-9 -a7 --trace=dup --trace-fds='!9' 9>>/dev/full dup-y -a8 --trace=dup -y 9>>/dev/full dup-yy -a8 --trace=dup -yy 9>>/dev/full dup2 -a11 9>>/dev/full dup2-P -a11 --trace=dup2 -P /dev/full 9>>/dev/full +dup2-e-fd-0 -a11 --trace=dup2 -e fd=0 9>>/dev/full +dup2-e-fd-0-9 -a11 --trace=dup2 -e fd=0,9 9>>/dev/full +dup2-e-fd-0-P -a11 --trace=dup2 -e fd=0 -P /dev/full 9>>/dev/full +dup2-e-fd-not-9 -a11 --trace=dup2 -e fd='!9' 9>>/dev/full dup2-y -a13 --trace=dup2 -y 9>>/dev/full dup2-yy -a13 --trace=dup2 -yy 9>>/dev/full dup3 -a13 7>>/dev/full @@ -697,9 +705,12 @@ pkey_alloc -a17 pkey_free -a13 pkey_mprotect -a37 poke-sendfile --trace=/sendfile --inject=all:poke_enter=@arg3=0000000000000000:poke_exit=@arg3=ffffffffffffffff -ppoll -s2 -ppoll-P -s2 -e trace=ppoll -P /dev/full 9>>/dev/full -ppoll-v -v -s2 -e trace=ppoll +ppoll -s2 +ppoll-P -s2 -e trace=ppoll -P /dev/full 9>>/dev/full +ppoll-e-trace-fds-23 -s2 -e trace=ppoll -e trace-fds=23 +ppoll-e-trace-fds-23-42 -s2 -e trace=ppoll -e trace-fds=23,42 +ppoll-e-trace-fds-not-9-42-P -s2 -e trace=ppoll -e trace-fds='!9,42' -P /dev/full 9>>/dev/full +ppoll-v -v -s2 -e trace=ppoll prctl-arg2-intptr +prctl.sh -a25 prctl-cap-ambient +prctl.sh -a21 prctl-capbset +prctl.sh -a21 @@ -892,6 +903,9 @@ segv_accerr -qq --trace=none segv_pkuerr -qq --trace=none select -a36 select-P -a36 -e trace=select -P /dev/full 9>>/dev/full +select-trace-fd-7 -a36 -e trace=select -e trace-fd=7 7>>/dev/null 9>>/dev/full +select-trace-fd-7-9 -a36 -e trace=select -e trace-fd=7,9 7>>/dev/null 9>>/dev/full +select-trace-fd-7-P -a36 -e trace=select -e trace-fd=7 -P /dev/full 7>>/dev/null 9>>/dev/full semop -a32 semop-indirect -a32 -e trace=semop semtimedop diff --git a/tests/options-syntax.test b/tests/options-syntax.test index c76c161d9..6af6b5963 100755 --- a/tests/options-syntax.test +++ b/tests/options-syntax.test @@ -286,6 +286,13 @@ check_e "invalid decode-pids ''" -e decode-pids= check_e "invalid decode-pids 'chdir'" --decode-pids=chdir check_e "invalid decode-pids 'gettid'" -e decode-pid=comm,gettid +check_h "must have PROG [ARGS] or -p PID" -e trace-fds=0 +check_h "must have PROG [ARGS] or -p PID" -e trace-fd=1,2,3 +check_h "must have PROG [ARGS] or -p PID" -e fd='!1' +check_h "must have PROG [ARGS] or -p PID" -e fds='!0,2147483647' +check_e "invalid descriptor '-1'" --trace-fds=-1 +check_e "invalid descriptor '2147483648'" --trace-fd=2147483648 + case "$STRACE_NATIVE_ARCH" in x86_64) check_h "must have PROG [ARGS] or -p PID" -e trace=getcwd@64 diff --git a/tests/ppoll-e-trace-fds-23-42.c b/tests/ppoll-e-trace-fds-23-42.c new file mode 100644 index 000000000..4291f2541 --- /dev/null +++ b/tests/ppoll-e-trace-fds-23-42.c @@ -0,0 +1,4 @@ +#define TRACING_FDS 1 +#define TRACING_FD1 23 +#define TRACING_FD2 42 +#include "ppoll.c" diff --git a/tests/ppoll-e-trace-fds-23.c b/tests/ppoll-e-trace-fds-23.c new file mode 100644 index 000000000..f88d51ea9 --- /dev/null +++ b/tests/ppoll-e-trace-fds-23.c @@ -0,0 +1,3 @@ +#define TRACING_FDS 1 +#define TRACING_FD1 23 +#include "ppoll.c" diff --git a/tests/ppoll-e-trace-fds-not-9-42-P.c b/tests/ppoll-e-trace-fds-not-9-42-P.c new file mode 100644 index 000000000..72653ee4f --- /dev/null +++ b/tests/ppoll-e-trace-fds-not-9-42-P.c @@ -0,0 +1,7 @@ +#define PATH_TRACING_FD 9 +#define TRACING_FDS 1 +#define TRACING_FD1 23 +#define TRACING_FD2 42 +#define TRACE_FD2 0 +#define TRACE_OTHER_FDS 1 +#include "ppoll.c" diff --git a/tests/ppoll.c b/tests/ppoll.c index 71f9ec2ae..bf3426fbf 100644 --- a/tests/ppoll.c +++ b/tests/ppoll.c @@ -20,6 +20,28 @@ # include # include +# ifndef PATH_TRACING_FD +# define PATH_TRACING_FD 0 +# endif +# ifndef TRACING_FDS +# define TRACING_FDS 0 +# endif +# ifndef TRACING_FD1 +# define TRACING_FD1 0 +# endif +# ifndef TRACING_FD2 +# define TRACING_FD2 0 +# endif +# ifndef TRACE_FD1 +# define TRACE_FD1 (!PATH_TRACING_FD && (!TRACING_FDS || TRACING_FD1)) +# endif +# ifndef TRACE_FD2 +# define TRACE_FD2 (!PATH_TRACING_FD && (!TRACING_FDS || TRACING_FD2)) +# endif +# ifndef TRACE_OTHER_FDS +# define TRACE_OTHER_FDS (!PATH_TRACING_FD && !TRACING_FDS) +# endif + static const char *errstr; static long @@ -37,7 +59,7 @@ sys_ppoll(const kernel_ulong_t ufds, int main(void) { -# ifdef PATH_TRACING_FD +# if PATH_TRACING_FD skip_if_unavailable("/proc/self/fd/"); # endif @@ -61,7 +83,7 @@ main(void) sys_ppoll(0, bogus_nfds, 0, 0, bogus_sigsetsize); if (ENOSYS == errno) perror_msg_and_skip("ppoll"); -# ifndef PATH_TRACING_FD +# if !PATH_TRACING_FD && !TRACING_FDS printf("ppoll(NULL, %u, NULL, NULL, %llu) = %s\n", (unsigned) bogus_nfds, (unsigned long long) bogus_sigsetsize, errstr); @@ -69,7 +91,7 @@ main(void) sys_ppoll((unsigned long) efault, 42, (unsigned long) efault + 8, (unsigned long) efault + 16, sigset_size); -# ifndef PATH_TRACING_FD +# if !PATH_TRACING_FD && !TRACING_FDS printf("ppoll(%p, %u, %p, %p, %u) = %s\n", efault, 42, efault + 8, efault + 16, sigset_size, errstr); # endif @@ -77,7 +99,7 @@ main(void) ts->tv_sec = 0xdeadbeefU; ts->tv_nsec = 0xfacefeedU; sys_ppoll(0, 0, (unsigned long) ts, 0, sigset_size); -# ifndef PATH_TRACING_FD +# if !PATH_TRACING_FD && !TRACING_FDS printf("ppoll(NULL, 0, {tv_sec=%lld, tv_nsec=%llu}, NULL, %u) = %s\n", (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec), sigset_size, errstr); @@ -86,7 +108,7 @@ main(void) ts->tv_sec = (time_t) 0xcafef00ddeadbeefLL; ts->tv_nsec = (long) 0xbadc0dedfacefeedL; sys_ppoll(0, 0, (unsigned long) ts, 0, sigset_size); -# ifndef PATH_TRACING_FD +# if !PATH_TRACING_FD && !TRACING_FDS printf("ppoll(NULL, 0, {tv_sec=%lld, tv_nsec=%llu}, NULL, %u) = %s\n", (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec), sigset_size, errstr); @@ -95,6 +117,20 @@ main(void) if (pipe(pipe_fd) || pipe(pipe_fd + 2)) perror_msg_and_fail("pipe"); +# if TRACING_FD1 + if (dup2(pipe_fd[3], TRACING_FD1) < 0) + perror_msg_and_fail("dup2 1"); + close(pipe_fd[3]); + pipe_fd[3] = TRACING_FD1; +# endif + +# if TRACING_FD2 + if (dup2(pipe_fd[1], TRACING_FD2) < 0) + perror_msg_and_fail("dup2 2"); + close(pipe_fd[1]); + pipe_fd[1] = TRACING_FD2; +# endif + ts->tv_sec = 42; ts->tv_nsec = 999999999; @@ -117,7 +153,7 @@ main(void) (unsigned long) sigmask, sigset_size); if (rc != 2) perror_msg_and_fail("ppoll 1"); -# ifndef PATH_TRACING_FD +# if TRACE_FD1 || TRACE_FD2 || TRACE_OTHER_FDS printf("ppoll([{fd=%d, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}" ", {fd=%d, events=POLLOUT%s|POLLWRBAND}" # if VERBOSE @@ -136,9 +172,30 @@ main(void) (unsigned int) sigset_size, rc, pipe_fd[1], POLLWRNORM_str, pipe_fd[3], (unsigned int) ts->tv_sec, (unsigned int) ts->tv_nsec); -# endif /* !PATH_TRACING_FD */ +# endif /* !PATH_TRACING_FDS */ -# ifdef PATH_TRACING_FD + ts->tv_sec = 23; + ts->tv_nsec = 123456789; + + rc = sys_ppoll((unsigned long) fds, + F8ILL_KULONG_MASK | (ARRAY_SIZE(fds1) - 2), + (unsigned long) ts, + (unsigned long) sigmask, sigset_size); + if (rc != 1) + perror_msg_and_fail("ppoll 1.5"); +# if TRACE_FD2 || TRACE_OTHER_FDS + printf("ppoll([{fd=%d, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}" + ", {fd=%d, events=POLLOUT%s|POLLWRBAND}]" + ", %u, {tv_sec=23, tv_nsec=123456789}, [%s], %u) = %ld" + " ([{fd=%d, revents=POLLOUT%s}]" + ", left {tv_sec=%u, tv_nsec=%u})\n", + pipe_fd[0], pipe_fd[1], POLLWRNORM_str, + (unsigned int) ARRAY_SIZE(fds1) - 2, USR2_CHLD_str, + (unsigned int) sigset_size, rc, pipe_fd[1], POLLWRNORM_str, + (unsigned int) ts->tv_sec, (unsigned int) ts->tv_nsec); +# endif /* !PATH_TRACING_FDS */ + +# if PATH_TRACING_FD ts->tv_sec = 123; ts->tv_nsec = 987654321; fds[3].fd = PATH_TRACING_FD; @@ -188,7 +245,7 @@ main(void) (unsigned long) sigmask, sigset_size); if (rc != 0) perror_msg_and_fail("ppoll 2"); -# ifndef PATH_TRACING_FD +# if TRACE_FD2 || TRACE_OTHER_FDS printf("ppoll([{fd=%d, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}" ", {fd=%d, events=POLLOUT%s|POLLWRBAND}], %u" ", {tv_sec=0, tv_nsec=999}, ~[HUP KILL STOP], %u)" @@ -197,11 +254,26 @@ main(void) (unsigned) ARRAY_SIZE(fds2), sigset_size, rc); # endif /* !PATH_TRACING_FD */ + ts->tv_sec = 0; + ts->tv_nsec = 1; + + rc = sys_ppoll((unsigned long) fds, + F8ILL_KULONG_MASK | 1, (unsigned long) ts, + (unsigned long) sigmask, sigset_size); + if (rc != 0) + perror_msg_and_fail("ppoll 2"); +# if !PATH_TRACING_FD && TRACE_FD2 + printf("ppoll([{fd=%d, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1" + ", {tv_sec=0, tv_nsec=1}, ~[HUP KILL STOP], %u)" + " = %ld (Timeout)\n", + pipe_fd[1], sigset_size, rc); +# endif /* !PATH_TRACING_FD */ + if (F8ILL_KULONG_SUPPORTED) { sys_ppoll(f8ill_ptr_to_kulong(fds), ARRAY_SIZE(fds2), f8ill_ptr_to_kulong(ts), f8ill_ptr_to_kulong(sigmask), sigset_size); -# ifndef PATH_TRACING_FD +# if !PATH_TRACING_FD && !TRACING_FDS printf("ppoll(%#llx, %u, %#llx, %#llx, %u) = %s\n", (unsigned long long) f8ill_ptr_to_kulong(fds), (unsigned) ARRAY_SIZE(fds2), diff --git a/tests/pure_executables.list b/tests/pure_executables.list index db527ee7b..331c4e1c7 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -51,10 +51,18 @@ dev--decode-fds-socket dev-yy dup dup-P +dup-trace-fds-0 +dup-trace-fds-0-9 +dup-trace-fds-0-P +dup-trace-fds-not-9 dup-y dup-yy dup2 dup2-P +dup2-e-fd-0 +dup2-e-fd-0-9 +dup2-e-fd-0-P +dup2-e-fd-not-9 dup2-y dup2-yy dup3 diff --git a/tests/select-trace-fd-7-9.c b/tests/select-trace-fd-7-9.c new file mode 100644 index 000000000..39993da94 --- /dev/null +++ b/tests/select-trace-fd-7-9.c @@ -0,0 +1,3 @@ +#define TRACING_FD 7 +#define PATH_TRACING_FD 9 +#include "select.c" diff --git a/tests/select-trace-fd-7-P.c b/tests/select-trace-fd-7-P.c new file mode 100644 index 000000000..39993da94 --- /dev/null +++ b/tests/select-trace-fd-7-P.c @@ -0,0 +1,3 @@ +#define TRACING_FD 7 +#define PATH_TRACING_FD 9 +#include "select.c" diff --git a/tests/select-trace-fd-7.c b/tests/select-trace-fd-7.c new file mode 100644 index 000000000..6aeaf180f --- /dev/null +++ b/tests/select-trace-fd-7.c @@ -0,0 +1,2 @@ +#define TRACING_FD 7 +#include "select.c" diff --git a/tests/xselect.c b/tests/xselect.c index fd7a48f03..ab53c7949 100644 --- a/tests/xselect.c +++ b/tests/xselect.c @@ -57,7 +57,21 @@ main(void) skip_if_unavailable("/proc/self/fd/"); #endif +#if defined(PATH_TRACING_FD) || defined(TRACING_FD) + static const int add_fd = +# ifdef PATH_TRACING_FD + PATH_TRACING_FD +# else + TRACING_FD +# endif + ; +#endif /* PATH_TRACING_FD || TRACING_FD */ + for (int i = 3; i < FD_SETSIZE; ++i) { +#ifdef TRACING_FD + if (i == TRACING_FD) + continue; +#endif #ifdef PATH_TRACING_FD if (i == PATH_TRACING_FD) continue; @@ -102,7 +116,7 @@ main(void) else perror_msg_and_fail(TEST_SYSCALL_STR); } -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(0, NULL, NULL, NULL, {tv_sec=%lld, tv_usec=%llu})" " = 0 (Timeout)\n", TEST_SYSCALL_STR, (long long) tv_in.tv_sec, @@ -111,7 +125,7 @@ main(void) /* EFAULT on tv argument */ XSELECT(-1, 0, 0, 0, 0, a_tv + 1); -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(0, NULL, NULL, NULL, %#lx) = %s\n", TEST_SYSCALL_STR, (unsigned long) a_tv + 1, errstr); #endif @@ -122,23 +136,43 @@ main(void) for (int i = nfds; i <= smallset_size; ++i) { *l_rs = (1UL << fds[0]) | (1UL << fds[1]); XSELECT(1, i, a_rs, a_rs, a_rs, 0); -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, [%d %d], [%d %d], [%d %d], NULL) = 1 ()\n", TEST_SYSCALL_STR, i, fds[0], fds[1], fds[0], fds[1], fds[0], fds[1]); -#else +#else /* PATH_TRACING_FD || TRACING_FD */ + *l_rs = (1UL << fds[0]) | (1UL << fds[1]) | (1UL << add_fd); + XSELECT(i > add_fd ? 3 : 1, i, a_rs, a_rs, a_rs, 0); + if (i > add_fd) { + printf("%s(%d, [%d %d %d], [%d %d %d], [%d %d %d]" + ", NULL) = 3 ()\n", + TEST_SYSCALL_STR, i, + fds[0], fds[1], add_fd, + fds[0], fds[1], add_fd, + fds[0], fds[1], add_fd); + } +#endif /* !PATH_TRACING_FD && !TRACING_FD */ +#if defined(PATH_TRACING_FD) && defined(TRACING_FD) *l_rs = (1UL << fds[0]) | (1UL << fds[1]) | - (1UL << PATH_TRACING_FD); - XSELECT(i > PATH_TRACING_FD ? 3 : 1, i, a_rs, a_rs, a_rs, 0); + (1UL << TRACING_FD) | (1UL << PATH_TRACING_FD); + XSELECT(1 + 2 * (!!(i > TRACING_FD) + !!(i > PATH_TRACING_FD)), + i, a_rs, a_rs, a_rs, 0); if (i > PATH_TRACING_FD) { + printf("%s(%d, [%d %d %d %d], [%d %d %d %d]" + ", [%d %d %d %d], NULL) = 5 ()\n", + TEST_SYSCALL_STR, i, + fds[0], fds[1], TRACING_FD, PATH_TRACING_FD, + fds[0], fds[1], TRACING_FD, PATH_TRACING_FD, + fds[0], fds[1], TRACING_FD, PATH_TRACING_FD); + } else if (i > TRACING_FD) { printf("%s(%d, [%d %d %d], [%d %d %d], [%d %d %d]" ", NULL) = 3 ()\n", TEST_SYSCALL_STR, i, - fds[0], fds[1], PATH_TRACING_FD, - fds[0], fds[1], PATH_TRACING_FD, - fds[0], fds[1], PATH_TRACING_FD); + fds[0], fds[1], TRACING_FD, + fds[0], fds[1], TRACING_FD, + fds[0], fds[1], TRACING_FD); } -#endif +#endif /* PATH_TRACING_FD && TRACING_FD */ } /* @@ -150,7 +184,7 @@ main(void) memcpy(tv, &tv_in, sizeof(tv_in)); rc = xselect(nfds, a_rs, a_rs, a_rs, a_tv); if (rc < 0) { -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, [%d %d], [%d %d], [%d %d]" ", {tv_sec=%lld, tv_usec=%llu}) = %s\n", TEST_SYSCALL_STR, nfds, fds[0], fds[1], @@ -158,9 +192,9 @@ main(void) (long long) tv_in.tv_sec, zero_extend_signed_to_ull(tv_in.tv_usec), errstr); -#endif /* !PATH_TRACING_FD */ +#endif /* PATH_TRACING_FD && TRACING_FD */ } else { -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, [%d %d], [%d %d], [%d %d]" ", {tv_sec=%lld, tv_usec=%llu}) = %ld" " (left {tv_sec=%lld, tv_usec=%llu})\n", @@ -170,7 +204,7 @@ main(void) zero_extend_signed_to_ull(tv_in.tv_usec), rc, (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec)); -#endif /* !PATH_TRACING_FD */ +#endif /* PATH_TRACING_FD && TRACING_FD */ } /* @@ -182,7 +216,7 @@ main(void) memcpy(tv, &tv_in, sizeof(tv_in)); rc = xselect(nfds, a_rs, a_rs, a_rs, a_tv); if (rc < 0) { -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, [%d %d], [%d %d], [%d %d]" ", {tv_sec=%lld, tv_usec=%llu}) = %s\n", TEST_SYSCALL_STR, nfds, fds[0], fds[1], @@ -190,9 +224,9 @@ main(void) (long long) tv_in.tv_sec, zero_extend_signed_to_ull(tv_in.tv_usec), errstr); -#endif /* PATH_TRACING_FD */ +#endif /* !PATH_TRACING_FD && !TRACING_FD */ } else { -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, [%d %d], [%d %d], [%d %d]" ", {tv_sec=%lld, tv_usec=%llu}) = %ld" " (left {tv_sec=%lld, tv_usec=%llu})\n", @@ -202,7 +236,7 @@ main(void) zero_extend_signed_to_ull(tv_in.tv_usec), rc, (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec)); -#endif /* PATH_TRACING_FD */ +#endif /* !PATH_TRACING_FD && !TRACING_FD */ } /* @@ -217,7 +251,7 @@ main(void) tv_in.tv_usec = 0xc0de2; memcpy(tv, &tv_in, sizeof(tv_in)); XSELECT(3, i, a_rs, a_ws, a_es, a_tv); -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, [%d %d], [%d %d %d %d], []" ", {tv_sec=%lld, tv_usec=%llu}) = 3 (out [1 2 %d]" ", left {tv_sec=%lld, tv_usec=%llu})\n", @@ -228,49 +262,47 @@ main(void) fds[1], (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec)); -#else - *l_rs = (1UL << fds[0]) | (1UL << fds[1]) | - (1UL << PATH_TRACING_FD); +#else /* PATH_TRACING_FD || TRACING_FD */ + *l_rs = (1UL << fds[0]) | (1UL << fds[1]) | (1UL << add_fd); *l_ws = (1UL << 1) | (1UL << 2) | (1UL << fds[0]) | (1UL << fds[1]); tv_in.tv_sec = 0xc0de1; tv_in.tv_usec = 0xc0de2; memcpy(tv, &tv_in, sizeof(tv_in)); - XSELECT(3 + (i > PATH_TRACING_FD), i, a_rs, a_ws, a_es, a_tv); - if (i > PATH_TRACING_FD) { + XSELECT(3 + (i > add_fd), i, a_rs, a_ws, a_es, a_tv); + if (i > add_fd) { printf("%s(%d, [%d %d %d], [%d %d %d %d], []" ", {tv_sec=%lld, tv_usec=%llu})" " = 4 (in [%d], out [1 2 %d]" ", left {tv_sec=%lld, tv_usec=%llu})\n", TEST_SYSCALL_STR, i, - fds[0], fds[1], PATH_TRACING_FD, + fds[0], fds[1], add_fd, 1, 2, fds[0], fds[1], (long long) tv_in.tv_sec, zero_extend_signed_to_ull(tv_in.tv_usec), - PATH_TRACING_FD, fds[1], + add_fd, fds[1], (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec)); } *l_rs = (1UL << fds[0]) | (1UL << fds[1]); *l_ws = (1UL << 1) | (1UL << 2) | - (1UL << fds[0]) | (1UL << fds[1]) | - (1UL << PATH_TRACING_FD); + (1UL << fds[0]) | (1UL << fds[1]) | (1UL << add_fd); tv_in.tv_sec = 0xc0de1; tv_in.tv_usec = 0xc0de2; memcpy(tv, &tv_in, sizeof(tv_in)); - XSELECT(3 + (i > PATH_TRACING_FD), i, a_rs, a_ws, a_es, a_tv); - if (i > PATH_TRACING_FD) { + XSELECT(3 + (i > add_fd), i, a_rs, a_ws, a_es, a_tv); + if (i > add_fd) { printf("%s(%d, [%d %d], [%d %d %d %d %d], []" ", {tv_sec=%lld, tv_usec=%llu})" " = 4 (out [1 2 %d %d]" ", left {tv_sec=%lld, tv_usec=%llu})\n", TEST_SYSCALL_STR, i, fds[0], fds[1], - 1, 2, fds[0], fds[1], PATH_TRACING_FD, + 1, 2, fds[0], fds[1], add_fd, (long long) tv_in.tv_sec, zero_extend_signed_to_ull(tv_in.tv_usec), - fds[1], PATH_TRACING_FD, + fds[1], add_fd, (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec)); } @@ -278,18 +310,18 @@ main(void) *l_rs = (1UL << fds[0]) | (1UL << fds[1]); *l_ws = (1UL << 1) | (1UL << 2) | (1UL << fds[0]) | (1UL << fds[1]); - *l_es = (1UL << PATH_TRACING_FD); + *l_es = (1UL << add_fd); tv_in.tv_sec = 0xc0de1; tv_in.tv_usec = 0xc0de2; memcpy(tv, &tv_in, sizeof(tv_in)); XSELECT(3, i, a_rs, a_ws, a_es, a_tv); - if (i > PATH_TRACING_FD) { + if (i > add_fd) { printf("%s(%d, [%d %d], [%d %d %d %d], [%d]" ", {tv_sec=%lld, tv_usec=%llu}) = 3 (out [1 2 %d]" ", left {tv_sec=%lld, tv_usec=%llu})\n", TEST_SYSCALL_STR, i, fds[0], fds[1], - 1, 2, fds[0], fds[1], PATH_TRACING_FD, + 1, 2, fds[0], fds[1], add_fd, (long long) tv_in.tv_sec, zero_extend_signed_to_ull(tv_in.tv_usec), fds[1], @@ -297,7 +329,7 @@ main(void) zero_extend_signed_to_ull(tv->tv_usec)); } -#endif /* PATH_TRACING_FD */ +#endif /* !PATH_TRACING_FD && !TRACING_FD */ } /* @@ -307,7 +339,7 @@ main(void) static fd_set set[0x1000000 / sizeof(fd_set)]; FD_SET(fds[1], set); XSELECT(-1, -1U, 0, (uintptr_t) set, 0, 0); -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(-1, NULL, %p, NULL, NULL) = %s\n", TEST_SYSCALL_STR, set, errstr); #endif @@ -329,22 +361,22 @@ main(void) tv->tv_sec = 0; tv->tv_usec = 10 + (i - FD_SETSIZE); XSELECT(0, i, a_big_rs, a_big_ws, 0, a_tv); -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, [%d], [], NULL, {tv_sec=0, tv_usec=%d})" " = 0 (Timeout)\n", TEST_SYSCALL_STR, i, fds[0], 10 + (i - FD_SETSIZE)); #else FD_SET(fds[0], big_rs); - FD_SET(PATH_TRACING_FD, big_rs); + FD_SET(add_fd, big_rs); tv->tv_sec = 0; tv->tv_usec = 10 + (i - FD_SETSIZE); XSELECT(1, i, a_big_rs, a_big_ws, 0, a_tv); printf("%s(%d, [%d %d], [], NULL, {tv_sec=0, tv_usec=%d})" " = 1 (in [%d], left {tv_sec=0, tv_usec=%llu})\n", - TEST_SYSCALL_STR, i, fds[0], PATH_TRACING_FD, - 10 + (i - FD_SETSIZE), PATH_TRACING_FD, + TEST_SYSCALL_STR, i, fds[0], add_fd, + 10 + (i - FD_SETSIZE), add_fd, zero_extend_signed_to_ull(tv->tv_usec)); -#endif /* PATH_TRACING_FD */ +#endif /* !PATH_TRACING_FD && !TRACING_FD */ } /* @@ -356,35 +388,41 @@ main(void) tv->tv_usec = 123; XSELECT(0, INT_MAX, (uintptr_t) set, (uintptr_t) &set[1], (uintptr_t) &set[2], a_tv); -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, [%d %d], [], [], {tv_sec=0, tv_usec=123})" " = 0 (Timeout)\n", TEST_SYSCALL_STR, INT_MAX, fds[0], fds[1]); #else FD_SET(fds[0], set); FD_SET(fds[1], set); - FD_SET(PATH_TRACING_FD, set); + FD_SET(add_fd, set); tv->tv_sec = 0; tv->tv_usec = 123; XSELECT(1, INT_MAX, (uintptr_t) set, (uintptr_t) &set[1], (uintptr_t) &set[2], a_tv); printf("%s(%d, [%d %d %d], [], [], {tv_sec=0, tv_usec=123})" " = 1 (in [%d], left {tv_sec=0, tv_usec=%llu})\n", - TEST_SYSCALL_STR, INT_MAX, fds[0], fds[1], PATH_TRACING_FD, - PATH_TRACING_FD, zero_extend_signed_to_ull(tv->tv_usec)); -#endif /* PATH_TRACING_FD */ + TEST_SYSCALL_STR, INT_MAX, fds[0], fds[1], add_fd, + add_fd, zero_extend_signed_to_ull(tv->tv_usec)); +#endif /* !PATH_TRACING_FD && !TRACING_FD */ /* * Small sets, nfds exceeds FD_SETSIZE limit. * The kernel seems to be fine with it but strace cannot follow. */ *l_rs = (1UL << fds[0]) | (1UL << fds[1]) +#ifdef TRACING_FD + | (1UL << TRACING_FD) +#endif #ifdef PATH_TRACING_FD | (1UL << PATH_TRACING_FD) #endif ; *l_ws = (1UL << fds[0]); *l_es = (1UL << fds[0]) | (1UL << fds[1]) +#ifdef TRACING_FD + | (1UL << TRACING_FD) +#endif #ifdef PATH_TRACING_FD | (1UL << PATH_TRACING_FD) #endif @@ -393,12 +431,12 @@ main(void) tv->tv_usec = 123; rc = xselect(FD_SETSIZE + 1, a_rs, a_ws, a_es, a_tv); if (rc < 0) { -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, %p, %p, %p, {tv_sec=0, tv_usec=123}) = %s\n", TEST_SYSCALL_STR, FD_SETSIZE + 1, rs, ws, es, errstr); #endif } else { -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, %p, %p, %p, {tv_sec=0, tv_usec=123})" " = 0 (Timeout)\n", TEST_SYSCALL_STR, FD_SETSIZE + 1, rs, ws, es); @@ -410,13 +448,18 @@ main(void) */ if (dup2(fds[1], smallset_size) != smallset_size) perror_msg_and_fail("dup2"); +#ifdef TRACING_FD + FD_SET(TRACING_FD, rs); + FD_SET(TRACING_FD, ws); + FD_SET(TRACING_FD, es); +#endif #ifdef PATH_TRACING_FD FD_SET(PATH_TRACING_FD, rs); FD_SET(PATH_TRACING_FD, ws); FD_SET(PATH_TRACING_FD, es); #endif XSELECT(-1, smallset_size + 1, a_rs, a_ws, a_es, 0); -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, %p, %p, %p, NULL) = %s\n", TEST_SYSCALL_STR, smallset_size + 1, rs, ws, es, errstr); #endif @@ -432,22 +475,22 @@ main(void) FD_SET(fds[1], big_ws); FD_SET(smallset_size, big_ws); XSELECT(-1, smallset_size + 1, a_big_rs, a_big_ws, a_es, 0); -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, [%d %d], [%d %d], %p, NULL) = %s\n", TEST_SYSCALL_STR, smallset_size + 1, fds[0], smallset_size, fds[1], smallset_size, es, errstr); -#endif /* !PATH_TRACING_FD */ +#endif /* !PATH_TRACING_FD && !TRACING_FD */ XSELECT(-1, smallset_size + 1, a_es, a_big_ws, a_big_rs, 0); -#ifndef PATH_TRACING_FD +#if !defined(PATH_TRACING_FD) && !defined(TRACING_FD) printf("%s(%d, %p, [%d %d], [%d %d], NULL) = %s\n", TEST_SYSCALL_STR, smallset_size + 1, es, fds[1], smallset_size, fds[0], smallset_size, errstr); -#endif /* !PATH_TRACING_FD */ +#endif /* !PATH_TRACING_FD && !TRACING_FD */ puts("+++ exited with 0 +++"); return 0; -- cgit v1.2.1