summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2023-04-04 22:06:18 +0200
committerDmitry V. Levin <ldv@strace.io>2023-04-22 08:00:00 +0000
commit67eb44c4de45e89af0e34937ff6a2ea1ebff14ae (patch)
treed1ef03cdbab754d32813ec0f85209656a3ad6d76
parent9800b413bc9412c2e3a118bd6a1c7e9ff99b5381 (diff)
downloadstrace-67eb44c4de45e89af0e34937ff6a2ea1ebff14ae.tar.gz
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) <GETOPT_QUAL_TRACE_FD>: New enum item. (init) <longopts>: Add"trace-fds" option. (init) <case GETOPT_QUAL_TRACE_FD>: 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 <maleisner@gmail.com> Link: https://lists.strace.io/pipermail/strace-devel/2023-March/011209.html
-rw-r--r--NEWS4
-rw-r--r--doc/strace.1.in17
-rw-r--r--src/defs.h8
-rw-r--r--src/filter_qualify.c14
-rw-r--r--src/number_set.h1
-rw-r--r--src/pathtrace.c58
-rw-r--r--src/strace.c8
-rw-r--r--src/syscall.c3
-rw-r--r--tests/.gitignore14
-rw-r--r--tests/Makefile.am6
-rw-r--r--tests/dup-P.c2
-rw-r--r--tests/dup-trace-fds-0-9.c4
-rw-r--r--tests/dup-trace-fds-0-P.c4
-rw-r--r--tests/dup-trace-fds-0.c3
-rw-r--r--tests/dup-trace-fds-not-9.c4
-rw-r--r--tests/dup.c29
-rw-r--r--tests/dup2-P.c2
-rw-r--r--tests/dup2-e-fd-0-9.c4
-rw-r--r--tests/dup2-e-fd-0-P.c5
-rw-r--r--tests/dup2-e-fd-0.c3
-rw-r--r--tests/dup2-e-fd-not-9.c4
-rw-r--r--tests/dup2.c59
-rw-r--r--tests/gen_tests.in20
-rwxr-xr-xtests/options-syntax.test7
-rw-r--r--tests/ppoll-e-trace-fds-23-42.c4
-rw-r--r--tests/ppoll-e-trace-fds-23.c3
-rw-r--r--tests/ppoll-e-trace-fds-not-9-42-P.c7
-rw-r--r--tests/ppoll.c92
-rwxr-xr-xtests/pure_executables.list8
-rw-r--r--tests/select-trace-fd-7-9.c3
-rw-r--r--tests/select-trace-fd-7-P.c3
-rw-r--r--tests/select-trace-fd-7.c2
-rw-r--r--tests/xselect.c151
33 files changed, 449 insertions, 107 deletions
diff --git a/NEWS b/NEWS
index c77140e6f..ba4d6a83f 100644
--- a/NEWS
+++ b/NEWS
@@ -2,9 +2,11 @@ Noteworthy changes in release ?.? (????-??-??)
==============================================
* Improvements
- * Updated lists of ioctl commands from Linux 6.3.
+ * Implemented -e trace-fds=set option for filtering only the syscalls
+ that operate on the specified set of file descriptors.
* Implemented -l/--syscall-limit option to automatically detach tracees
after capturing the specified number of syscalls.
+ * 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 c40d9b7ba..16a94fc7d 100644
--- a/doc/strace.1.in
+++ b/doc/strace.1.in
@@ -251,6 +251,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 ),
@@ -659,6 +660,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
@@ -739,6 +755,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 245958772..37812e0bc 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;
extern long long syscall_limit;
struct path_set_item {
@@ -799,7 +801,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)
@@ -810,7 +813,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);
}
/**
@@ -1402,6 +1405,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;
@@ -496,6 +497,15 @@ qualify_trace(const char *const str)
}
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)
{
if (!abbrev_set)
@@ -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 cea445fe2..0f34e8961 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;
long long syscall_limit = -1;
static bool nflag;
static int tflag_scale = 1000000000;
@@ -336,6 +337,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\
@@ -2263,6 +2266,7 @@ init(int argc, char *argv[])
GETOPT_TIPS,
GETOPT_QUAL_TRACE,
+ GETOPT_QUAL_TRACE_FD,
GETOPT_QUAL_ABBREV,
GETOPT_QUAL_VERBOSE,
GETOPT_QUAL_RAW,
@@ -2323,6 +2327,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 },
@@ -2563,6 +2568,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 696b81dfd..120e68f59 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 f5c8e4496..83f1e96f6 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 2f1c90795..dfffb8c2c 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..c9c0f50aa 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 74d9984c9..6432e3409 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 f6fcd95f5..328eb30c5 100755
--- a/tests/options-syntax.test
+++ b/tests/options-syntax.test
@@ -290,6 +290,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 <string.h>
# include <unistd.h>
+# 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;