summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolay Marchuk <marchuk.nikolay.a@gmail.com>2017-08-27 19:42:28 +0700
committerDmitry V. Levin <ldv@altlinux.org>2018-06-13 15:05:09 +0000
commitc2a98548700365dc28ef34ff897a4fd7ee08f5d2 (patch)
tree068fb1e613f4e7255581ecd95a494ae5ae8cfb05
parentf1bba432e1b6b2b9c165212a9cfd52c2d826ca0e (diff)
downloadstrace-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.c12
-rw-r--r--basic_filters.c23
-rw-r--r--defs.h4
-rw-r--r--filter.c1
-rw-r--r--filter.h3
-rw-r--r--filter_action.c2
-rw-r--r--filter_qualify.c30
-rw-r--r--number_set.h2
-rw-r--r--syscall.c4
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;
+}
diff --git a/defs.h b/defs.h
index a13b01174..0482e7f47 100644
--- a/defs.h
+++ b/defs.h
@@ -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)
diff --git a/filter.c b/filter.c
index 9ac00356a..0c10ba030 100644
--- a/filter.c
+++ b/filter.c
@@ -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
diff --git a/filter.h b/filter.h
index 0bc4be8b9..f88a7192a 100644
--- a/filter.h
+++ b/filter.h
@@ -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 */
diff --git a/syscall.c b/syscall.c
index aad9aa4c0..df19b7585 100644
--- a/syscall.c
+++ b/syscall.c
@@ -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: