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:
parent
f1bba432e1
commit
c2a9854870
@ -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;
|
||||
}
|
||||
|
@ -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
4
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)
|
||||
|
1
filter.c
1
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
|
||||
|
||||
|
3
filter.h
3
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) \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user