* basic_actions.c (parse_inject, parse_fault, apply_fault): Implement. (apply_inject): Change inject private data. * defs.h (inject_vec): Remove. (inject_opts): Add init flag. * filter.h (parse_inject_token): Add definition. * filter_action.c: Add fault action. * filter_qualify.c (parse_inject_common): Generate new inject private data. --- basic_actions.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++------ defs.h | 2 +- filter.h | 2 ++ filter_action.c | 3 ++ filter_qualify.c | 42 ++++++++++--------------- 5 files changed, 108 insertions(+), 36 deletions(-)
diff --git a/basic_actions.c b/basic_actions.c index de87cde..1eb597e 100644 --- a/basic_actions.c +++ b/basic_actions.c @@ -25,6 +25,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "defs.h" +#include "filter.h" bool is_traced(struct tcb *tcp) @@ -49,50 +50,134 @@ apply_trace(struct tcb *tcp, void *_priv_data) { tcp->qual_flg |= QUAL_TRACE; } + +struct inject_priv_data { + struct inject_opts opts; + struct inject_opts **inject_vec; +}; + void apply_inject(struct tcb *tcp, void *_priv_data) { - struct inject_opts **inject_vec = (struct inject_opts **)_priv_data; + struct inject_priv_data *data = (struct inject_priv_data *)_priv_data; + struct inject_opts *opts; + if (!(scno_in_range(tcp->scno) && data->inject_vec[current_personality])) + return; + opts = &data->inject_vec[current_personality][tcp->scno]; + if (!opts->init) { + data->inject_vec[current_personality][tcp->scno] = data->opts; + opts = &data->inject_vec[current_personality][tcp->scno]; + opts->init = true; + } tcp->qual_flg |= QUAL_INJECT; - tcp->inject_opts = (scno_in_range(tcp->scno) && inject_vec[current_personality]) - ? &inject_vec[current_personality][tcp->scno] : NULL; + tcp->inject_opts = opts; } -void* + +static void * +parse_inject_common_args(const char *const str, + const bool fault_tokens_only, + const char *const description) +{ + struct inject_priv_data *data = xmalloc(sizeof(struct inject_priv_data)); + data->inject_vec = xcalloc(SUPPORTED_PERSONALITIES, + sizeof(struct inject_opts *)); + unsigned int p; + for (p = 0; p < SUPPORTED_PERSONALITIES; ++p) { + data->inject_vec[p] = xcalloc(nsyscall_vec[p], + sizeof(struct inject_opts)); + } + data->opts.first = 1; + data->opts.step = 1; + data->opts.rval = INJECT_OPTS_RVAL_DEFAULT; + data->opts.signo = 0; + if (!str) { + if (fault_tokens_only) { + data->opts.rval = -ENOSYS; + return data; + } else { + error_msg_and_die("inject argument is required"); + } + } + char *buf = xstrdup(str); + char *saveptr = NULL; + char *token; + for (token = strtok_r(buf, ";", &saveptr); token; + token = strtok_r(NULL, ";", &saveptr)) { + if (!parse_inject_token(token, &data->opts, fault_tokens_only)) + error_msg_and_die("invalid %s argument '%s'", + description, token); + } + free(buf); + if (data->opts.rval == INJECT_OPTS_RVAL_DEFAULT && !data->opts.signo) { + if (fault_tokens_only) { + data->opts.rval = -ENOSYS; + } else { + error_msg_and_die("invalid %s arguments '%s'", + description, str); + } + } + return data; +} + +void * parse_inject(const char *str) { - return NULL; + return parse_inject_common_args(str, false, "inject"); } + void free_inject(void *_priv_data) { - struct inject_opts **vec = (struct inject_opts **)_priv_data; + struct inject_priv_data *data = (struct inject_priv_data *)_priv_data; unsigned int p; for (p = 0; p < SUPPORTED_PERSONALITIES; ++p) - if (vec[p]) - free(vec[p]); - free(vec); + if (data->inject_vec[p]) + free(data->inject_vec[p]); + free(data->inject_vec); + free(data); } + 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; } + void apply_raw(struct tcb *tcp, void *_priv_data) { tcp->qual_flg |= QUAL_RAW; } + void apply_abbrev(struct tcb *tcp, void *_priv_data) { tcp->qual_flg |= QUAL_ABBREV; } + void apply_verbose(struct tcb *tcp, void *_priv_data) { tcp->qual_flg |= QUAL_VERBOSE; } + +void * +parse_fault(const char *str) +{ + return parse_inject_common_args(str, true, "fault"); +} + +void +apply_fault(struct tcb *tcp, void *_priv_data) +{ + apply_inject(tcp, _priv_data); +} + +void free_fault(void *_priv_data) { + free_inject(_priv_data); +} diff --git a/defs.h b/defs.h index 9242b16..21dec65 100644 --- a/defs.h +++ b/defs.h @@ -203,6 +203,7 @@ struct inject_opts { uint16_t step; uint16_t signo; int rval; + bool init; }; #define MAX_ERRNO_VALUE 4095 @@ -970,7 +971,6 @@ extern unsigned nioctlents; extern const unsigned int nsyscall_vec[SUPPORTED_PERSONALITIES]; extern const struct_sysent *const sysent_vec[SUPPORTED_PERSONALITIES]; -extern struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES]; #ifdef IN_MPERS_BOOTSTRAP /* Transform multi-line MPERS_PRINTER_DECL statements to one-liners. */ diff --git a/filter.h b/filter.h index ed435c8..7e03d75 100644 --- a/filter.h +++ b/filter.h @@ -41,6 +41,8 @@ extern bool is_traced(struct tcb *); typedef int (*string_to_uint_func)(const char *); void parse_set(const char *const, struct number_set *const, string_to_uint_func, const char *const); +bool parse_inject_token(const char *const, struct inject_opts *const, + const bool); struct filter* add_filter_to_array(struct filter **, unsigned int *nfilters, const char *name); diff --git a/filter_action.c b/filter_action.c index f71f140..fd3fa92 100644 --- a/filter_action.c +++ b/filter_action.c @@ -34,6 +34,7 @@ apply_ ## name(struct tcb *, void *) DECL_FILTER_ACTION(trace); DECL_FILTER_ACTION(inject); +DECL_FILTER_ACTION(fault); DECL_FILTER_ACTION(read); DECL_FILTER_ACTION(write); DECL_FILTER_ACTION(raw); @@ -50,6 +51,7 @@ free_ ## name(void *) DECL_FILTER_ACTION_PARSER(null); DECL_FILTER_ACTION_PARSER(inject); +DECL_FILTER_ACTION_PARSER(fault); #undef DECL_FILTER_ACTION_PARSER @@ -68,6 +70,7 @@ static const struct filter_action_type { } action_types[] = { FILTER_ACTION_TYPE(trace, 2, null, NULL), FILTER_ACTION_TYPE(inject, 2, inject, NULL), + FILTER_ACTION_TYPE(fault, 2, fault, NULL), FILTER_ACTION_TYPE(read, 1, null, is_traced), FILTER_ACTION_TYPE(write, 1, null, is_traced), FILTER_ACTION_TYPE(raw, 1, null, is_traced), diff --git a/filter_qualify.c b/filter_qualify.c index 6020ce8..79c1202 100644 --- a/filter_qualify.c +++ b/filter_qualify.c @@ -80,7 +80,7 @@ sigstr_to_uint(const char *s) return -1; } -static bool +bool parse_inject_token(const char *const token, struct inject_opts *const fopts, const bool fault_tokens_only) { @@ -233,6 +233,11 @@ parse_raw(const char *const str) set_qualify_mode(action); } +struct inject_priv_data { + struct inject_opts opts; + struct inject_opts **inject_vec; +}; + static void parse_inject_common(const char *const str, const bool fault_tokens_only, @@ -242,7 +247,8 @@ parse_inject_common(const char *const str, .first = 1, .step = 1, .rval = INJECT_OPTS_RVAL_DEFAULT, - .signo = 0 + .signo = 0, + .init = true }; char *buf = NULL; char *name = parse_inject_expression(str, &buf, &opts, fault_tokens_only); @@ -265,35 +271,19 @@ parse_inject_common(const char *const str, struct filter *filter = create_filter(action, "syscall"); parse_filter(filter, name, description); set_qualify_mode(action); - free(buf); - const struct number_set *tmp_set = (const struct number_set *) - get_filter_priv_data(filter); - struct inject_opts **inject_vec = xcalloc(SUPPORTED_PERSONALITIES, - sizeof(struct inject_opts *)); - /* - * Initialize inject_vec accourding to tmp_set. - */ + + struct inject_priv_data *data = xmalloc(sizeof(struct inject_priv_data)); + data->opts = opts; + data->inject_vec = xcalloc(SUPPORTED_PERSONALITIES, + sizeof(struct inject_opts *)); unsigned int p; for (p = 0; p < SUPPORTED_PERSONALITIES; ++p) { - if (is_empty(&tmp_set[p])) { - continue; - } - - if (!inject_vec[p]) { - inject_vec[p] = xcalloc(nsyscall_vec[p], - sizeof(*inject_vec[p])); - } - - unsigned int i; - for (i = 0; i < nsyscall_vec[p]; ++i) { - if (is_number_in_set(i, &tmp_set[p])) { - inject_vec[p][i] = opts; - } - } + data->inject_vec[p] = xcalloc(nsyscall_vec[p], + sizeof(struct inject_opts)); } - set_filter_action_priv_data(action, inject_vec); + set_filter_action_priv_data(action, data); } static void -- 2.1.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel