summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@strace.io>2022-01-15 08:00:00 +0000
committerDmitry V. Levin <ldv@strace.io>2022-01-15 08:00:00 +0000
commit29571af829595c837526f7e9de0c310e708ecf66 (patch)
tree19d1f9c6b04b25f664e3304b3f314d3f693d1897
parentc5e3c47765d7a6553b4127c7caa9c0bfe04006bd (diff)
downloadstrace-29571af829595c837526f7e9de0c310e708ecf66.tar.gz
Extend personality designation syntax to support %class@pers
* NEWS: Mention this. * src/basic_filters.c (qualify_syscall_number, qualify_syscall_number_personality): Squash into a new function qualify_syscall_number taking personality as an argument instead of iterating over all personalities, remove personality designation syntax support. (qualify_syscall_regex): Change to take personality as an argument instead of iterating over all personalities, remove personality designation syntax support. (qualify_syscall_class): Change to take personality as an argument instead of iterating over all personalities. (qualify_syscall_name): Remove. (qualify_syscall_name_personality): Rename to qualify_syscall_name. (qualify_syscall_pers): New function. (qualify_syscall): Use it to iterate over all supported personalities, add personality designation syntax support. * src/strace.c (usage): Update --trace description. * doc/strace.1.in (.SS Filtering): Likewise. * tests/options-syntax.test: Update expected output. * tests/trace_personality_statfs_32.in: New file. * tests/trace_personality_statfs_64.in: Likewise. * tests/trace_personality_statfs_x32.in: Likewise. * tests/Makefile.am (EXTRA_DIST): Add them. * tests/gen_tests.in (trace_personality_statfs_32, trace_personality_statfs_64, trace_personality_statfs_x32): New tests.
-rw-r--r--NEWS2
-rw-r--r--doc/strace.1.in30
-rw-r--r--src/basic_filters.c145
-rw-r--r--src/strace.c4
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/gen_tests.in3
-rwxr-xr-xtests/options-syntax.test3
-rw-r--r--tests/trace_personality_statfs_32.in2
-rw-r--r--tests/trace_personality_statfs_64.in2
-rw-r--r--tests/trace_personality_statfs_x32.in2
10 files changed, 80 insertions, 116 deletions
diff --git a/NEWS b/NEWS
index 4a34d98c1..f52ca8bec 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ Noteworthy changes in release ?.?? (????-??-??)
* Improvements
* Added 64-bit LoongArch architecture support.
+ * Extended personality designation syntax of syscall specification expressions
+ to support %class@pers.
* Bug fixes
diff --git a/doc/strace.1.in b/doc/strace.1.in
index 9474116ae..9ae53faf6 100644
--- a/doc/strace.1.in
+++ b/doc/strace.1.in
@@ -487,6 +487,21 @@ Trace specific syscall, specified by its name (but see
Question mark before the syscall qualification allows suppression of error
in case no syscalls matched the qualification provided.
.TP
+.IB value @64
+Limit the syscall specification described by
+.I value
+to 64-bit personality.
+.TP
+.IB value @32
+Limit the syscall specification described by
+.I value
+to 32-bit personality.
+.TP
+.IB value @x32
+Limit the syscall specification described by
+.I value
+to x32 personality.
+.TP
.BI / regex
Trace only those system calls that match the
.IR regex .
@@ -495,21 +510,6 @@ You can use
Extended Regular Expression syntax (see
.BR regex (7)).
.TP
-.IB syscall @64
-Trace
-.I syscall
-only for the 64-bit personality.
-.TP
-.IB syscall @32
-Trace
-.I syscall
-only for the 32-bit personality.
-.TP
-.IB syscall @x32
-Trace
-.I syscall
-only for the 32-on-64-bit personality.
-.TP
.B %file
.TQ
.BR file
diff --git a/src/basic_filters.c b/src/basic_filters.c
index 01f755f4e..50142bc55 100644
--- a/src/basic_filters.c
+++ b/src/basic_filters.c
@@ -51,46 +51,17 @@ qualify_syscall_separate_personality(const char *s, unsigned int *p)
}
static bool
-qualify_syscall_number_personality(int n, unsigned int p,
- struct number_set *set)
+qualify_syscall_number(const char *str, unsigned int p, struct number_set *set)
{
- if ((unsigned int) n >= nsyscall_vec[p])
+ unsigned int n = string_to_uint(str);
+
+ if (n >= nsyscall_vec[p])
return false;
add_number_to_set_array(n, set, p);
-
return true;
}
-static bool
-qualify_syscall_number(const char *s, struct number_set *set)
-{
- unsigned int p;
- char *num_str = qualify_syscall_separate_personality(s, &p);
- int n;
-
- if (num_str) {
- n = string_to_uint(num_str);
- free(num_str);
-
- if (n < 0)
- return false;
-
- return qualify_syscall_number_personality(n, p, set);
- }
-
- n = string_to_uint(s);
- if (n < 0)
- return false;
-
- bool done = false;
-
- for (p = 0; p < SUPPORTED_PERSONALITIES; ++p)
- done |= qualify_syscall_number_personality(n, p, set);
-
- return done;
-}
-
static void
regerror_msg_and_die(int errcode, const regex_t *preg,
const char *str, const char *pattern)
@@ -102,43 +73,29 @@ regerror_msg_and_die(int errcode, const regex_t *preg,
}
static bool
-qualify_syscall_regex(const char *s, struct number_set *set)
+qualify_syscall_regex(const char *str, unsigned int p, struct number_set *set)
{
regex_t preg;
int rc;
- if ((rc = regcomp(&preg, s, REG_EXTENDED | REG_NOSUB)) != 0)
- regerror_msg_and_die(rc, &preg, "regcomp", s);
+ if ((rc = regcomp(&preg, str, REG_EXTENDED | REG_NOSUB)) != 0)
+ regerror_msg_and_die(rc, &preg, "regcomp", str);
bool found = false;
- for (unsigned int p = 0; p < SUPPORTED_PERSONALITIES; ++p) {
- for (unsigned int i = 0; i < nsyscall_vec[p]; ++i) {
- if (!sysent_vec[p][i].sys_name)
- continue;
+ for (unsigned int i = 0; i < nsyscall_vec[p]; ++i) {
+ if (!sysent_vec[p][i].sys_name)
+ continue;
- rc = regexec(&preg, sysent_vec[p][i].sys_name,
- 0, NULL, 0);
+ rc = regexec(&preg, sysent_vec[p][i].sys_name,
+ 0, NULL, 0);
+ if (rc == REG_NOMATCH)
+ continue;
+ else if (rc)
+ regerror_msg_and_die(rc, &preg, "regexec", str);
- if (rc == REG_NOMATCH) {
- char name_buf[128];
- char *pos = stpcpy(name_buf,
- sysent_vec[p][i].sys_name);
-
- (void) xappendstr(name_buf, pos, "@%s",
- personality_designators[p]);
-
- rc = regexec(&preg, name_buf, 0, NULL, 0);
- }
-
- if (rc == REG_NOMATCH)
- continue;
- else if (rc)
- regerror_msg_and_die(rc, &preg, "regexec", s);
-
- add_number_to_set_array(i, set, p);
- found = true;
- }
+ add_number_to_set_array(i, set, p);
+ found = true;
}
regfree(&preg);
@@ -189,18 +146,16 @@ lookup_class(const char *s)
}
static bool
-qualify_syscall_class(const char *s, struct number_set *set)
+qualify_syscall_class(const char *str, unsigned int p, struct number_set *set)
{
- const unsigned int n = lookup_class(s);
+ const unsigned int n = lookup_class(str);
if (!n)
return false;
- for (unsigned int p = 0; p < SUPPORTED_PERSONALITIES; ++p) {
- for (unsigned int i = 0; i < nsyscall_vec[p]; ++i) {
- if (sysent_vec[p][i].sys_name &&
- (sysent_vec[p][i].sys_flags & n) == n)
- add_number_to_set_array(i, set, p);
- }
+ for (unsigned int i = 0; i < nsyscall_vec[p]; ++i) {
+ if (sysent_vec[p][i].sys_name &&
+ (sysent_vec[p][i].sys_flags & n) == n)
+ add_number_to_set_array(i, set, p);
}
return true;
@@ -222,8 +177,7 @@ scno_by_name(const char *s, unsigned int p, kernel_long_t start)
}
static bool
-qualify_syscall_name_personality(const char *s, unsigned int p,
- struct number_set *set)
+qualify_syscall_name(const char *s, unsigned int p, struct number_set *set)
{
bool found = false;
@@ -237,41 +191,36 @@ qualify_syscall_name_personality(const char *s, unsigned int p,
}
static bool
-qualify_syscall_name(const char *s, struct number_set *set)
+qualify_syscall_pers(const char *token, unsigned int p, struct number_set *set)
{
- unsigned int p;
- char *name_str = qualify_syscall_separate_personality(s, &p);
- bool found = false;
-
- if (name_str) {
- found = qualify_syscall_name_personality(name_str, p, set);
- free(name_str);
-
- return found;
- }
-
- for (p = 0; p < SUPPORTED_PERSONALITIES; ++p)
- found |= qualify_syscall_name_personality(s, p, set);
-
- return found;
+ if (*token >= '0' && *token <= '9')
+ return qualify_syscall_number(token, p, set);
+ if (*token == '/')
+ return qualify_syscall_regex(token + 1, p, set);
+ return qualify_syscall_class(token, p, set)
+ || qualify_syscall_name(token, p, set);
}
static bool
qualify_syscall(const char *token, struct number_set *set)
{
- bool ignore_fail = false;
-
+ bool rc = false;
while (*token == '?') {
- token++;
- ignore_fail = true;
+ ++token;
+ rc = true;
}
- if (*token >= '0' && *token <= '9')
- return qualify_syscall_number(token, set) || ignore_fail;
- if (*token == '/')
- return qualify_syscall_regex(token + 1, set) || ignore_fail;
- return qualify_syscall_class(token, set)
- || qualify_syscall_name(token, set)
- || ignore_fail;
+
+ unsigned int p;
+ char *str = qualify_syscall_separate_personality(token, &p);
+ if (str) {
+ rc |= qualify_syscall_pers(str, p, set);
+ free(str);
+ } else {
+ for (p = 0; p < SUPPORTED_PERSONALITIES; ++p)
+ rc |= qualify_syscall_pers(token, p, set);
+ }
+
+ return rc;
}
/*
diff --git a/src/strace.c b/src/strace.c
index 7370275e1..b4631bdcc 100644
--- a/src/strace.c
+++ b/src/strace.c
@@ -317,8 +317,8 @@ Tracing:\n\
(useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
\n\
Filtering:\n\
- -e trace=[!]{[?]SYSCALL[@64|@32|@x32]|[?]/REGEX|GROUP|all|none},\n\
- --trace=[!]{[?]SYSCALL[@64|@32|@x32]|[?]/REGEX|GROUP|all|none}\n\
+ -e trace=[!][?]{{SYSCALL|GROUP|/REGEX}[@64|@32|@x32]|all|none},\n\
+ --trace=[!][?]{{SYSCALL|GROUP|/REGEX}[@64|@32|@x32]|all|none}\n\
trace only specified syscalls.\n\
groups: %%clock, %%creds, %%desc, %%file, %%fstat, %%fstatfs %%ipc, %%lstat,\n\
%%memory, %%net, %%process, %%pure, %%signal, %%stat, %%%%stat,\n\
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0ef79e83a..859a912f6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -725,6 +725,9 @@ EXTRA_DIST = \
trace_personality_regex_32.in \
trace_personality_regex_64.in \
trace_personality_regex_x32.in \
+ trace_personality_statfs_32.in \
+ trace_personality_statfs_64.in \
+ trace_personality_statfs_x32.in \
trace_personality_x32.in \
trace_question.in \
trace_stat.in \
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 4ed45fc73..1509dc08a 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -1006,6 +1006,9 @@ trace_personality_number_x32 +qualify_personality.sh x32 "$(${srcdir=.}/print_sc
trace_personality_regex_32 +qualify_personality.sh 32 '/clock.*' 'times|times-.*|fcntl.*'
trace_personality_regex_64 +qualify_personality.sh 64 '/clock.*' 'times|times-.*|fcntl.*'
trace_personality_regex_x32 +qualify_personality.sh x32 '/clock.*' 'times|times-.*|fcntl.*'
+trace_personality_statfs_32 +qualify_personality.sh 32 '%statfs'
+trace_personality_statfs_64 +qualify_personality.sh 64 '%statfs'
+trace_personality_statfs_x32 +qualify_personality.sh x32 '%statfs'
trace_personality_x32 +qualify_personality.sh x32 'getcwd' 'fsync-y|poke'
trace_question test_trace_expr '' -e?osf_utimes,?/^pkey_.*
trace_stat test_trace_expr '' -e%stat -v -P stat.sample -P /dev/full
diff --git a/tests/options-syntax.test b/tests/options-syntax.test
index aecf4eb30..64385cec8 100755
--- a/tests/options-syntax.test
+++ b/tests/options-syntax.test
@@ -216,6 +216,8 @@ check_h "incorrect personality designator '' in qualification 'getcwd@'" -e trac
check_h "incorrect personality designator '42' in qualification 'getcwd@42'" -e trace=getcwd@42
check_h "incorrect personality designator '42' in qualification 'getcwd@42'" -e trace=gettid,getcwd@42
check_h "incorrect personality designator '42' in qualification '23@42'" -e trace=23@42,123
+check_h "incorrect personality designator 'ohmy' in qualification '/getcwd@ohmy'" \
+ -e trace=/getcwd@ohmy
check_h '--seccomp-bpf cannot be used without -f/--follow-forks, disabling
-w/--summary-wall-clock must be given with (-c/--summary-only or -C/--summary)' --seccomp-bpf -w /
@@ -229,7 +231,6 @@ check_h 'option -F is deprecated, please use -f/--follow-forks instead
check_h 'deprecated option -F ignored
-w/--summary-wall-clock must be given with (-c/--summary-only or -C/--summary)' -fF -w /
-check_e "invalid system call '/getcwd@ohmy'" -e trace=/getcwd@ohmy
check_e "invalid -e kvm= argument: 'chdir'" -e kvm=chdir
check_e "invalid -e kvm= argument: 'chdir'" --kvm=chdir
diff --git a/tests/trace_personality_statfs_32.in b/tests/trace_personality_statfs_32.in
new file mode 100644
index 000000000..7c4adfe10
--- /dev/null
+++ b/tests/trace_personality_statfs_32.in
@@ -0,0 +1,2 @@
+statfs -a17
+statfs64 -a23
diff --git a/tests/trace_personality_statfs_64.in b/tests/trace_personality_statfs_64.in
new file mode 100644
index 000000000..7c4adfe10
--- /dev/null
+++ b/tests/trace_personality_statfs_64.in
@@ -0,0 +1,2 @@
+statfs -a17
+statfs64 -a23
diff --git a/tests/trace_personality_statfs_x32.in b/tests/trace_personality_statfs_x32.in
new file mode 100644
index 000000000..7c4adfe10
--- /dev/null
+++ b/tests/trace_personality_statfs_x32.in
@@ -0,0 +1,2 @@
+statfs -a17
+statfs64 -a23