diff options
author | Dmitry V. Levin <ldv@strace.io> | 2022-01-15 08:00:00 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@strace.io> | 2022-01-15 08:00:00 +0000 |
commit | 29571af829595c837526f7e9de0c310e708ecf66 (patch) | |
tree | 19d1f9c6b04b25f664e3304b3f314d3f693d1897 | |
parent | c5e3c47765d7a6553b4127c7caa9c0bfe04006bd (diff) | |
download | strace-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-- | NEWS | 2 | ||||
-rw-r--r-- | doc/strace.1.in | 30 | ||||
-rw-r--r-- | src/basic_filters.c | 145 | ||||
-rw-r--r-- | src/strace.c | 4 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/gen_tests.in | 3 | ||||
-rwxr-xr-x | tests/options-syntax.test | 3 | ||||
-rw-r--r-- | tests/trace_personality_statfs_32.in | 2 | ||||
-rw-r--r-- | tests/trace_personality_statfs_64.in | 2 | ||||
-rw-r--r-- | tests/trace_personality_statfs_x32.in | 2 |
10 files changed, 80 insertions, 116 deletions
@@ -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 |