summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2023-05-03 16:00:32 +0200
committerDmitry V. Levin <ldv@strace.io>2023-05-05 12:02:38 +0000
commitbcab1dd027d0b3e3d84aad4f8d8f5a1d17bbec31 (patch)
tree72c61b15d27ae6bc9d9f7e9ff8cb79a1261fcc37
parent5bfbcdc03ba59c03c13e0241ee9bad3e411aca0c (diff)
downloadstrace-bcab1dd027d0b3e3d84aad4f8d8f5a1d17bbec31.tar.gz
syscall: fix -c (CFLAG_ONLY_STATS) usage in conjunction with -e and -l
* src/syscall.c (syscall_exiting_trace): Move cflag handling right before tprint_arg_end() and in the res != 1 code path, avoid printing anything if cflag is set to CFLAG_ONLY_STATS. * tests/.gitignore: Add strace--syscall-limit-c and strace--syscall-limit-status-c. * tests/Makefile.am (check_PROGRAMS): Likewise. * tests/gen_tests.in (strace--syscall-limit-c, strace--syscall-limit-status-c): New tests. * tests/strace--syscall-limit-c.c: New file. * tests/strace--syscall-limit-status-c.c: Likewise. * tests/strace--syscall-limit-status-summary.c: Likewise. * tests/strace--syscall-limit-summary.c: Likewise. * tests/strace--syscall-limit.c [!PRINT_INVALID] (PRINT_INVALID): New macro, set to 1. [!PRINT_STATS] (PRINT_STATS): New macro, set to 0. [!UNLINKAT_CNT] (UNLINKAT_CNT): New macro, set to 1. [!TOTAL_CNT] (TOTAL_CNT): New macro, set to 3. (test_chdir, test_rmdir) [!PRINT_INVALID]: Do not print syscalls with non-zero return value. (main) [PRINT_STATS]: Print the expected syscall statistics output. * NEWS: Mention it. Fixes: v5.2~6 "Implement -e status=set option" Fixes: v6.2-13-gac1d1e25d "Introduce -l/--syscall-limit options"
-rw-r--r--NEWS1
-rw-r--r--src/syscall.c76
-rw-r--r--tests/.gitignore4
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/gen_tests.in4
-rw-r--r--tests/strace--syscall-limit-c.c4
-rw-r--r--tests/strace--syscall-limit-status-c.c6
-rw-r--r--tests/strace--syscall-limit-status-summary.c5
-rw-r--r--tests/strace--syscall-limit-summary.c2
-rw-r--r--tests/strace--syscall-limit.c42
10 files changed, 111 insertions, 37 deletions
diff --git a/NEWS b/NEWS
index 6cdeb64a5..40c4cb048 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,7 @@ Noteworthy changes in release ?.? (????-??-??)
* Bug fixes
* Fixed build on hppa with uapi headers from Linux >= 6.2.
+ * Fixed -e status= filtering when -c option is in use.
Noteworthy changes in release 6.2 (2023-02-26)
==============================================
diff --git a/src/syscall.c b/src/syscall.c
index 018580ae0..c636ba37c 100644
--- a/src/syscall.c
+++ b/src/syscall.c
@@ -796,46 +796,48 @@ syscall_exiting_trace(struct tcb *tcp, struct timespec *ts, int res)
inject_poke_exit(tcp))
tamper_with_syscall_exiting(tcp);
- if (cflag) {
- count_syscall(tcp, ts);
- if (cflag == CFLAG_ONLY_STATS) {
- return 0;
- }
- }
-
- print_syscall_resume(tcp);
+ if (cflag != CFLAG_ONLY_STATS)
+ print_syscall_resume(tcp);
tcp->s_prev_ent = NULL;
if (res != 1) {
- /* There was error in one of prior ptrace ops */
- tprint_arg_end();
- tprint_space();
- tabto();
- tprint_sysret_begin();
- tprints_sysret_next("retval");
- tprint_sysret_pseudo_rval();
- tprints_sysret_next("return");
- tprints_string("<unavailable>");
- tprint_sysret_end();
- tprint_newline();
- if (!is_complete_set(status_set, NUMBER_OF_STATUSES)) {
- bool publish = is_number_in_set(STATUS_UNAVAILABLE,
- status_set);
- strace_close_memstream(tcp, publish);
+ /* There was an error in one of prior ptrace ops. */
+ bool status_filtering =
+ !is_complete_set(status_set, NUMBER_OF_STATUSES);
+ bool publish = status_filtering
+ ? is_number_in_set(STATUS_UNAVAILABLE, status_set)
+ : true;
+ if (cflag && publish)
+ count_syscall(tcp, ts);
+ if (cflag != CFLAG_ONLY_STATS) {
+ tprint_arg_end();
+ tprint_space();
+ tabto();
+ tprint_sysret_begin();
+ tprints_sysret_next("retval");
+ tprint_sysret_pseudo_rval();
+ tprints_sysret_next("return");
+ tprints_string("<unavailable>");
+ tprint_sysret_end();
+ tprint_newline();
+ if (status_filtering)
+ strace_close_memstream(tcp, publish);
+ line_ended();
}
- line_ended();
return res;
}
tcp->s_prev_ent = tcp->s_ent;
int sys_res = 0;
- if (raw(tcp)) {
- /* sys_res = printargs(tcp); - but it's nop on sysexit */
- } else {
- if (tcp->sys_func_rval & RVAL_DECODED)
- sys_res = tcp->sys_func_rval;
- else
- sys_res = tcp_sysent(tcp)->sys_func(tcp);
+ if (cflag != CFLAG_ONLY_STATS) {
+ if (raw(tcp)) {
+ /* sys_res = printargs(tcp); - but it's nop on sysexit */
+ } else {
+ if (tcp->sys_func_rval & RVAL_DECODED)
+ sys_res = tcp->sys_func_rval;
+ else
+ sys_res = tcp_sysent(tcp)->sys_func(tcp);
+ }
}
if (!is_complete_set(status_set, NUMBER_OF_STATUSES)) {
@@ -843,9 +845,11 @@ syscall_exiting_trace(struct tcb *tcp, struct timespec *ts, int res)
&& is_number_in_set(STATUS_FAILED, status_set);
publish |= !syserror(tcp)
&& is_number_in_set(STATUS_SUCCESSFUL, status_set);
- strace_close_memstream(tcp, publish);
+ if (cflag != CFLAG_ONLY_STATS)
+ strace_close_memstream(tcp, publish);
if (!publish) {
- line_ended();
+ if (cflag != CFLAG_ONLY_STATS)
+ line_ended();
return 0;
}
}
@@ -853,6 +857,12 @@ syscall_exiting_trace(struct tcb *tcp, struct timespec *ts, int res)
if (syscall_limit != -1)
syscall_limit--;
+ if (cflag) {
+ count_syscall(tcp, ts);
+ if (cflag == CFLAG_ONLY_STATS)
+ return 0;
+ }
+
tprint_arg_end();
tprint_space();
tabto();
diff --git a/tests/.gitignore b/tests/.gitignore
index 15073a0f9..d9272ba33 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1049,8 +1049,12 @@ strace--strings-in-hex-non-ascii
strace--strings-in-hex-non-ascii-chars
strace--strings-in-hex-none
strace--syscall-limit
+strace--syscall-limit-c
strace--syscall-limit-path
strace--syscall-limit-status
+strace--syscall-limit-status-c
+strace--syscall-limit-status-summary
+strace--syscall-limit-summary
strace-Y-0123456789
strace-n
strace-no-x
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f25c2a506..d91841635 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -392,8 +392,12 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
status-unfinished-threads \
strace--decode-pids-comm \
strace--syscall-limit \
+ strace--syscall-limit-c \
strace--syscall-limit-path \
strace--syscall-limit-status \
+ strace--syscall-limit-status-c \
+ strace--syscall-limit-status-summary \
+ strace--syscall-limit-summary \
strace-Y-0123456789 \
strace-p-Y-p2 \
strace-p1-Y-p \
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 98bee712a..a1a0b7320 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -1034,8 +1034,12 @@ strace--strings-in-hex-all --trace=chdir --strings-in-hex=all --columns=18
strace--strings-in-hex-non-ascii --trace=chdir --strings-in-hex=non-ascii --columns=12
strace--strings-in-hex-non-ascii-chars --trace=chdir --strings-in-hex=non-ascii-chars --columns=12
strace--strings-in-hex-none --trace=chdir --strings-in-hex=none --columns=12
+strace--syscall-limit-c +strace--syscall-limit.test -c -S syscall -U calls
strace--syscall-limit-path +strace--syscall-limit.test --trace-path=invalid.dir
strace--syscall-limit-status +strace--syscall-limit.test --status=failed
+strace--syscall-limit-status-c +strace--syscall-limit.test --status=failed -l 4 -c -S syscall -U calls
+strace--syscall-limit-status-summary +strace--syscall-limit.test --status=failed -l 4 --summary -S syscall -U calls
+strace--syscall-limit-summary +strace--syscall-limit.test -C -S syscall -U calls
strace--syscall-times +strace-T_upper.test --syscall-times
strace--syscall-times-ms +strace-T_upper.test --syscall-times=ms
strace--syscall-times-ns +strace-T_upper.test --syscall-times=ns
diff --git a/tests/strace--syscall-limit-c.c b/tests/strace--syscall-limit-c.c
new file mode 100644
index 000000000..e7b999951
--- /dev/null
+++ b/tests/strace--syscall-limit-c.c
@@ -0,0 +1,4 @@
+#define PRINT_VALID 0
+#define PRINT_INVALID 0
+#define PRINT_STATS 1
+#include "strace--syscall-limit.c"
diff --git a/tests/strace--syscall-limit-status-c.c b/tests/strace--syscall-limit-status-c.c
new file mode 100644
index 000000000..ff661aa47
--- /dev/null
+++ b/tests/strace--syscall-limit-status-c.c
@@ -0,0 +1,6 @@
+#define PRINT_VALID 0
+#define PRINT_INVALID 0
+#define PRINT_STATS 1
+#define UNLINKAT_CNT 2
+#define TOTAL_CNT 4
+#include "strace--syscall-limit.c"
diff --git a/tests/strace--syscall-limit-status-summary.c b/tests/strace--syscall-limit-status-summary.c
new file mode 100644
index 000000000..1c9e2b66f
--- /dev/null
+++ b/tests/strace--syscall-limit-status-summary.c
@@ -0,0 +1,5 @@
+#define PRINT_VALID 0
+#define PRINT_STATS 1
+#define UNLINKAT_CNT 2
+#define TOTAL_CNT 4
+#include "strace--syscall-limit.c"
diff --git a/tests/strace--syscall-limit-summary.c b/tests/strace--syscall-limit-summary.c
new file mode 100644
index 000000000..0325fa38f
--- /dev/null
+++ b/tests/strace--syscall-limit-summary.c
@@ -0,0 +1,2 @@
+#define PRINT_STATS 1
+#include "strace--syscall-limit.c"
diff --git a/tests/strace--syscall-limit.c b/tests/strace--syscall-limit.c
index 260337d49..3d8739224 100644
--- a/tests/strace--syscall-limit.c
+++ b/tests/strace--syscall-limit.c
@@ -21,6 +21,18 @@
#ifndef PRINT_VALID
# define PRINT_VALID 1
#endif
+#ifndef PRINT_INVALID
+# define PRINT_INVALID 1
+#endif
+#ifndef PRINT_STATS
+# define PRINT_STATS 0
+#endif
+#ifndef UNLINKAT_CNT
+# define UNLINKAT_CNT 1
+#endif
+#ifndef TOTAL_CNT
+# define TOTAL_CNT 3
+#endif
static int
write_status(const char *name, int value)
@@ -48,11 +60,13 @@ test_chdir(int pid, bool print)
if (print) {
#if PRINT_VALID
printf("%-5u chdir(\"%s\") = 0\n", pid, valid_path);
-#else
+#else /* !PRINT_VALID */
if (chdir(invalid_path) == 0)
error_msg_and_fail("chdir: %s", invalid_path);
+# if PRINT_INVALID
printf("%-5u chdir(\"%s\") = %s\n", pid, invalid_path, sprintrc(-1));
-#endif
+# endif
+#endif /* PRINT_VALID */
} else {
if (chdir(invalid_path) == 0)
error_msg_and_fail("chdir: %s", invalid_path);
@@ -70,9 +84,11 @@ test_rmdir(int pid, bool print)
#endif
if (syscall(__NR_unlinkat, AT_FDCWD, "invalid.dir", AT_REMOVEDIR) == 0)
error_msg_and_fail("unlinkat: %s", invalid_path);
+#if PRINT_INVALID
if (print)
printf("%-5u unlinkat(AT_FDCWD, \"%s\", AT_REMOVEDIR) = %s\n",
pid, invalid_path, sprintrc(-1));
+#endif
}
int
@@ -93,9 +109,12 @@ main(void)
test_rmdir(pid, /* print */ true);
test_chdir(pid, /* print */ true);
- /* the tracer is expected to detach at this point */
+ /*
+ * the tracer is expected to detach at this point
+ * if TOTAL_CNT < 4.
+ */
- test_rmdir(pid, /* print */ false);
+ test_rmdir(pid, /* print */ TOTAL_CNT > 3);
exit(0);
}
@@ -111,6 +130,21 @@ main(void)
test_chdir(pid, /* print */ false);
+#if PRINT_STATS
+# if defined MPERS_IS_m32
+ printf("System call usage summary for 32 bit mode:\n");
+# endif
+# if defined MPERS_IS_mx32
+ printf("System call usage summary for x32 mode:\n");
+# endif
+ printf("%9s %s\n", "calls", "syscall");
+ printf("--------- ----------------\n");
+ printf("%9d %s\n", 2, "chdir");
+ printf("%9d %s\n", UNLINKAT_CNT, "unlinkat");
+ printf("--------- ----------------\n");
+ printf("%9d %s\n", TOTAL_CNT, "total");
+#endif /* PRINT_STATS */
+
return write_status("parent_status",
WIFEXITED(status) ? WEXITSTATUS(status) : 1);
}