lkml.org 
[lkml]   [2009]   [Aug]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH v2 3/3] tracing/filters: Support filtering for char * strings
    Usually, char * entries are dangerous in traces because the string
    can be released whereas a pointer to it can still wait to be read from
    the ring buffer.

    But sometimes we can assume it's safe, like in case of RO data
    (eg: __file__ or __line__, used in bkl trace event). If these RO data
    are in a module and so is the call to the trace event, then it's safe,
    because the ring buffer will be flushed once this module get unloaded.

    To allow char * to be treated as a string:

    TRACE_EVENT(...,

    TP_STRUCT__entry(
    __field_ext(const char *, name, FILTER_PTR_STRING)
    ...
    )

    ...
    );

    Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
    ---
    include/linux/ftrace_event.h | 1 +
    kernel/trace/trace_events_filter.c | 26 +++++++++++++++++++++++---
    2 files changed, 24 insertions(+), 3 deletions(-)

    diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
    index f034e8f..fd5f329 100644
    --- a/include/linux/ftrace_event.h
    +++ b/include/linux/ftrace_event.h
    @@ -140,6 +140,7 @@ enum {
    FILTER_OTHER = 0,
    FILTER_STATIC_STRING,
    FILTER_DYN_STRING,
    + FILTER_PTR_STRING,
    };

    extern int trace_define_field(struct ftrace_event_call *call, char *type,
    diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
    index 5e7f031..b16923e 100644
    --- a/kernel/trace/trace_events_filter.c
    +++ b/kernel/trace/trace_events_filter.c
    @@ -163,6 +163,20 @@ static int filter_pred_string(struct filter_pred *pred, void *event,
    return match;
    }

    +/* Filter predicate for char * pointers */
    +static int filter_pred_pchar(struct filter_pred *pred, void *event,
    + int val1, int val2)
    +{
    + char **addr = (char **)(event + pred->offset);
    + int cmp, match;
    +
    + cmp = strncmp(*addr, pred->str_val, pred->str_len);
    +
    + match = (!cmp) ^ pred->not;
    +
    + return match;
    +}
    +
    /*
    * Filter predicate for dynamic sized arrays of characters.
    * These are implemented through a list of strings at the end
    @@ -489,7 +503,8 @@ int filter_assign_type(const char *type)
    static bool is_string_field(struct ftrace_event_field *field)
    {
    return field->filter_type == FILTER_DYN_STRING ||
    - field->filter_type == FILTER_STATIC_STRING;
    + field->filter_type == FILTER_STATIC_STRING ||
    + field->filter_type == FILTER_PTR_STRING;
    }

    static int is_legal_op(struct ftrace_event_field *field, int op)
    @@ -579,11 +594,16 @@ static int filter_add_pred(struct filter_parse_state *ps,
    }

    if (is_string_field(field)) {
    + pred->str_len = field->size;
    +
    if (field->filter_type == FILTER_STATIC_STRING)
    fn = filter_pred_string;
    - else
    + else if (field->filter_type == FILTER_DYN_STRING)
    fn = filter_pred_strloc;
    - pred->str_len = field->size;
    + else {
    + fn = filter_pred_pchar;
    + pred->str_len = strlen(pred->str_val);
    + }
    } else {
    if (field->is_signed)
    ret = strict_strtoll(pred->str_val, 0, &val);
    --
    1.6.3


    \
     
     \ /
      Last update: 2009-08-07 04:37    [W:0.025 / U:61.060 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site