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]
This commit is contained in:
Nikolay Marchuk 2017-08-27 19:42:28 +07:00 committed by Dmitry V. Levin
parent f1bba432e1
commit c2a9854870
9 changed files with 59 additions and 22 deletions

View File

@ -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;
}

View File

@ -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;
}

4
defs.h
View File

@ -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)

View File

@ -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

View File

@ -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) \

View File

@ -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

View File

@ -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
@ -251,22 +249,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)
{
@ -286,6 +268,18 @@ qualify_filter(const char *const str, const char *const action_name,
set_qualify_mode(action);
}
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)
{

View File

@ -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 */

View File

@ -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: