diff options
author | Nikolay Marchuk <marchuk.nikolay.a@gmail.com> | 2017-08-27 19:42:28 +0700 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2018-06-13 15:05:09 +0000 |
commit | c2a98548700365dc28ef34ff897a4fd7ee08f5d2 (patch) | |
tree | 068fb1e613f4e7255581ecd95a494ae5ae8cfb05 | |
parent | f1bba432e1b6b2b9c165212a9cfd52c2d826ca0e (diff) | |
download | strace-c2a98548700365dc28ef34ff897a4fd7ee08f5d2.tar.gz |
Implement fd filter and read/write actions
* basic_actions.c (apply_read, apply_write): New functions.
* basic_filters.c (parse_fd_filter, run_fd_filter, free_fd_filter): Likewise.
* defs.h (QUAL_READ, QUAL_WRITE): Add new flags.
(dump_read, dump_write): Add macros for these flags.
* filter.c (filter_types): Add fd filter type.
* filter.h (DECL_FILTER): Add fd filter declaration.
(DECL_FILTER_ACTION): Add read and write filter action declarations.
* filter_action.c (action_types): Add read and write filter action types.
* filter_qualify.c (read_set, write_set): Remove set variables.
(qualify_read, qualify_write): Use new filtering API.
* number_set.h (read_set, write_set): Remove set variable declarations.
* syscall.c (dumpio): Check dump_read, dump_write macros
instead of global sets.
[ldv: simplify *_qualify_mode]
[ldv: cleanup run_fd_filter]
-rw-r--r-- | basic_actions.c | 12 | ||||
-rw-r--r-- | basic_filters.c | 23 | ||||
-rw-r--r-- | defs.h | 4 | ||||
-rw-r--r-- | filter.c | 1 | ||||
-rw-r--r-- | filter.h | 3 | ||||
-rw-r--r-- | filter_action.c | 2 | ||||
-rw-r--r-- | filter_qualify.c | 30 | ||||
-rw-r--r-- | number_set.h | 2 | ||||
-rw-r--r-- | syscall.c | 4 |
9 files changed, 59 insertions, 22 deletions
diff --git a/basic_actions.c b/basic_actions.c index d07dcea04..3047c28c9 100644 --- a/basic_actions.c +++ b/basic_actions.c @@ -110,3 +110,15 @@ parse_fault(const char *str) { return parse_inject_common(str, true, "fault"); } + +void +apply_read(struct tcb *tcp, void *_priv_data) +{ + tcp->qual_flg |= QUAL_READ; +} + +void +apply_write(struct tcb *tcp, void *_priv_data) +{ + tcp->qual_flg |= QUAL_WRITE; +} diff --git a/basic_filters.c b/basic_filters.c index a7ed571f8..a83290731 100644 --- a/basic_filters.c +++ b/basic_filters.c @@ -333,3 +333,26 @@ qualify_tokens(const char *const str, struct number_set *const set, if (number < 0) error_msg_and_die("invalid %s '%s'", name, str); } + +void * +parse_fd_filter(const char *str) +{ + struct number_set *set = alloc_number_set_array(1); + qualify_tokens(str, set, string_to_uint, "descriptor"); + return set; +} + +bool +run_fd_filter(struct tcb *tcp, void *priv_data) +{ + int fd = tcp->u_arg[0]; + + return fd < 0 ? false : is_number_in_set(fd, priv_data); +} + +void +free_fd_filter(void *priv_data) +{ + free_number_set_array(priv_data, 1); + return; +} @@ -268,6 +268,8 @@ struct tcb { #define QUAL_VERBOSE 0x004 /* decode the structures of this syscall */ #define QUAL_RAW 0x008 /* print all args in hex for this syscall */ #define QUAL_INJECT 0x010 /* tamper with this system call on purpose */ +#define QUAL_READ 0x020 /* dump data read in this syscall */ +#define QUAL_WRITE 0x040 /* dump data written in this syscall */ #define DEFAULT_QUAL_FLAGS (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE) @@ -277,6 +279,8 @@ struct tcb { #define traced(tcp) ((tcp)->qual_flg & QUAL_TRACE) #define verbose(tcp) ((tcp)->qual_flg & QUAL_VERBOSE) #define abbrev(tcp) ((tcp)->qual_flg & QUAL_ABBREV) +#define dump_read(tcp) ((tcp)->qual_flg & QUAL_READ) +#define dump_write(tcp) ((tcp)->qual_flg & QUAL_WRITE) #define raw(tcp) ((tcp)->qual_flg & QUAL_RAW) #define inject(tcp) ((tcp)->qual_flg & QUAL_INJECT) #define filtered(tcp) ((tcp)->flags & TCB_FILTERED) @@ -40,6 +40,7 @@ static const struct filter_type { void (*free_priv_data)(void *); } filter_types[] = { FILTER_TYPE(syscall), + FILTER_TYPE(fd), }; #undef FILTER_TYPE @@ -76,6 +76,7 @@ free_ ## name ## _filter(void *) \ /* End of DECL_FILTER definition. */ DECL_FILTER(syscall); +DECL_FILTER(fd); #undef DECL_FILTER #define DECL_FILTER_ACTION(name) \ @@ -89,6 +90,8 @@ DECL_FILTER_ACTION(abbrev); DECL_FILTER_ACTION(verbose); DECL_FILTER_ACTION(inject); DECL_FILTER_ACTION(fault); +DECL_FILTER_ACTION(read); +DECL_FILTER_ACTION(write); #undef DECL_FILTER_ACTION #define DECL_FILTER_ACTION_PARSER(name) \ diff --git a/filter_action.c b/filter_action.c index c404a2094..20cb9cfc4 100644 --- a/filter_action.c +++ b/filter_action.c @@ -47,6 +47,8 @@ static const struct filter_action_type { FILTER_ACTION_TYPE(raw, 2, QUAL_RAW, NULL, is_traced), FILTER_ACTION_TYPE(abbrev, 2, QUAL_ABBREV, NULL, is_traced), FILTER_ACTION_TYPE(verbose, 2, QUAL_VERBOSE, NULL, is_traced), + FILTER_ACTION_TYPE(read, 2, QUAL_READ, NULL, is_traced), + FILTER_ACTION_TYPE(write, 2, QUAL_WRITE, NULL, is_traced), }; #undef FILTER_ACTION_TYPE diff --git a/filter_qualify.c b/filter_qualify.c index 809a1ee45..37012db9d 100644 --- a/filter_qualify.c +++ b/filter_qualify.c @@ -33,8 +33,6 @@ #include "delay.h" #include "retval.h" -struct number_set *read_set; -struct number_set *write_set; struct number_set *signal_set; static int @@ -252,22 +250,6 @@ parse_inject_common_args(char *const str, struct inject_opts *const opts, } static void -qualify_read(const char *const str) -{ - if (!read_set) - read_set = alloc_number_set_array(1); - qualify_tokens(str, read_set, string_to_uint, "descriptor"); -} - -static void -qualify_write(const char *const str) -{ - if (!write_set) - write_set = alloc_number_set_array(1); - qualify_tokens(str, write_set, string_to_uint, "descriptor"); -} - -static void qualify_signals(const char *const str) { if (!signal_set) @@ -287,6 +269,18 @@ qualify_filter(const char *const str, const char *const action_name, } static void +qualify_read(const char *const str) +{ + qualify_filter(str, "read", "fd"); +} + +static void +qualify_write(const char *const str) +{ + qualify_filter(str, "write", "fd"); +} + +static void qualify_trace(const char *const str) { qualify_filter(str, "trace", "syscall"); diff --git a/number_set.h b/number_set.h index ec53bc1b6..f3b9f312c 100644 --- a/number_set.h +++ b/number_set.h @@ -59,8 +59,6 @@ alloc_number_set_array(unsigned int nmemb) ATTRIBUTE_MALLOC; extern void free_number_set_array(struct number_set *, unsigned int nmemb); -extern struct number_set *read_set; -extern struct number_set *write_set; extern struct number_set *signal_set; #endif /* !STRACE_NUMBER_SET_H */ @@ -386,7 +386,7 @@ dumpio(struct tcb *tcp) if (fd < 0) return; - if (is_number_in_set(fd, write_set)) { + if (dump_write(tcp)) { switch (tcp->s_ent->sen) { case SEN_write: case SEN_pwrite: @@ -413,7 +413,7 @@ dumpio(struct tcb *tcp) if (syserror(tcp)) return; - if (is_number_in_set(fd, read_set)) { + if (dump_read(tcp)) { switch (tcp->s_ent->sen) { case SEN_read: case SEN_pread: |