* basic_filters.c (parse_path_filter, run_path_filter, free_path_filter):
New functions.
* filter.c (filter_types): Add path filter type.
(set_filter_priv_data): New function.
* filter.h (set_filter_priv_data, expression_add_filter_and):
Add declarations.
(DECL_FILTER): Add path filter declaration.
* filter_action.c (inject_path_tracing): New function.
(filtering_parse_finish): Use it.
* filter_expression.c (add_variable_token, add_operator_token,
expression_add_filter_and): New functions.
* pathtrace.c (storepath): Duplicate path.
---
 basic_filters.c     | 30 ++++++++++++++++++++++++++++++
 filter.c            |  8 ++++++++
 filter.h            |  3 +++
 filter_action.c     | 18 ++++++++++++++++++
 filter_expression.c | 26 ++++++++++++++++++++++++++
 pathtrace.c         |  2 +-
 6 files changed, 86 insertions(+), 1 deletion(-)

diff --git a/basic_filters.c b/basic_filters.c
index 54b52fed..da3bb80d 100644
--- a/basic_filters.c
+++ b/basic_filters.c
@@ -375,3 +375,33 @@ free_fd_filter(void *priv_data)
        free_number_set_array(set, 1);
        return;
 }
+
+void *
+parse_path_filter(const char *path)
+{
+       struct path_set *set = xcalloc(1, sizeof(struct path_set));
+
+       pathtrace_select_set(path, set);
+       return set;
+}
+
+bool
+run_path_filter(struct tcb *tcp, void *priv_data)
+{
+       struct path_set *set = priv_data;
+
+       return pathtrace_match_set(tcp, set);
+}
+
+void
+free_path_filter(void *priv_data)
+{
+       struct path_set *set = priv_data;
+       unsigned int i;
+
+       for (i = 0; i < set->num_selected; ++i)
+               free((char *) set->paths_selected[i]);
+       free(set->paths_selected);
+       free(set);
+       return;
+}
diff --git a/filter.c b/filter.c
index a7d93de7..9b996cf5 100644
--- a/filter.c
+++ b/filter.c
@@ -41,6 +41,7 @@ static const struct filter_type {
 } filter_types[] = {
        FILTER_TYPE(syscall),
        FILTER_TYPE(fd),
+       FILTER_TYPE(path),
 };
 #undef FILTER_TYPE
 
@@ -120,3 +121,10 @@ set_filters_qualify_mode(struct filter **filters, unsigned 
int *nfilters,
        *filters = xreallocarray(*filters, filters_left, sizeof(struct filter));
        *nfilters = filters_left;
 }
+
+void
+set_filter_priv_data(struct filter *filter, void *priv_data)
+{
+       if (filter)
+               filter->priv_data = priv_data;
+}
diff --git a/filter.h b/filter.h
index 886da1b4..47ac5503 100644
--- a/filter.h
+++ b/filter.h
@@ -56,6 +56,7 @@ void run_filters(struct tcb *, struct filter *, unsigned int, 
bool *);
 void free_filter(struct filter *);
 void set_filters_qualify_mode(struct filter **, unsigned int *nfilters,
                              unsigned int filters_left);
+void set_filter_priv_data(struct filter *, void *);
 
 /* filter action api */
 struct filter *create_filter(struct filter_action *, const char *name);
@@ -67,6 +68,7 @@ void set_filter_action_priv_data(struct filter_action *, void 
*);
 struct bool_expression *create_expression();
 bool run_expression(struct bool_expression *, bool *, unsigned int);
 void set_expression_qualify_mode(struct bool_expression *, unsigned int);
+void expression_add_filter_and(struct bool_expression *, unsigned int);
 
 #define DECL_FILTER(name)                                              \
 extern void *                                                          \
@@ -79,6 +81,7 @@ free_ ## name ## _filter(void *)                              
        \
 
 DECL_FILTER(syscall);
 DECL_FILTER(fd);
+DECL_FILTER(path);
 #undef DECL_FILTER
 
 #define DECL_FILTER_ACTION(name)                                       \
diff --git a/filter_action.c b/filter_action.c
index b403ca3a..fb8c3c1d 100644
--- a/filter_action.c
+++ b/filter_action.c
@@ -86,12 +86,30 @@ compare_action_priority(const void *a, const void *b)
        }
 }
 
+static void
+inject_path_tracing(void)
+{
+       struct filter_action *action = find_or_add_action("trace");
+       struct filter *path_filter;
+
+       if (!action->nfilters)
+               qualify("trace=all");
+       path_filter = add_filter_to_array(&action->filters, &action->nfilters,
+                                         "path");
+       set_filter_priv_data(path_filter, &global_path_set);
+       expression_add_filter_and(action->expr, action->nfilters - 1);
+}
+
 void
 filtering_parsing_finish(void)
 {
        unsigned int maxfilters = 0;
        unsigned int i;
 
+       /* Inject path filter into trace action. */
+       if (tracing_paths)
+               inject_path_tracing();
+
        /* Sort actions by priority */
        if (nfilter_actions == 0)
                return;
diff --git a/filter_expression.c b/filter_expression.c
index 4c1ff466..73aaae3a 100644
--- a/filter_expression.c
+++ b/filter_expression.c
@@ -69,6 +69,32 @@ reallocate_expression(struct bool_expression *const expr,
        expr->ntokens = new_ntokens;
 }
 
+static void
+add_variable_token(struct bool_expression *expr, unsigned int id)
+{
+       struct expression_token token;
+       token.type = TOK_VARIABLE;
+       token.data.variable_id = id;
+       reallocate_expression(expr, expr->ntokens + 1);
+       expr->tokens[expr->ntokens - 1] = token;
+}
+
+static void
+add_operator_token(struct bool_expression *expr, int op) {
+       struct expression_token token;
+       token.type = TOK_OPERATOR;
+       token.data.operator_id = op;
+       reallocate_expression(expr, expr->ntokens + 1);
+       expr->tokens[expr->ntokens - 1] = token;
+}
+
+void
+expression_add_filter_and(struct bool_expression *expr, unsigned int filter_id)
+{
+       add_variable_token(expr, filter_id);
+       add_operator_token(expr, OP_AND);
+}
+
 void
 set_expression_qualify_mode(struct bool_expression *expr,
                            unsigned int filters_left)
diff --git a/pathtrace.c b/pathtrace.c
index 52582380..23a352ef 100644
--- a/pathtrace.c
+++ b/pathtrace.c
@@ -91,7 +91,7 @@ storepath(const char *path, struct path_set *set)
        set->paths_selected = xreallocarray(set->paths_selected,
                                            set->num_selected,
                                            sizeof(set->paths_selected[0]));
-       set->paths_selected[i] = path;
+       set->paths_selected[i] = xstrdup(path);
 }
 
 /*
-- 
2.11.0


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

Reply via email to