aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/traceevent/parse-filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/traceevent/parse-filter.c')
-rw-r--r--tools/lib/traceevent/parse-filter.c86
1 files changed, 57 insertions, 29 deletions
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index dfcfe2c131de..ad17855528f9 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -96,7 +96,7 @@ static enum event_type read_token(char **tok)
(strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
pevent_peek_char() == '~') {
/* append it */
- *tok = malloc(3);
+ *tok = malloc_or_die(3);
sprintf(*tok, "%c%c", *token, '~');
free_token(token);
/* Now remove the '~' from the buffer */
@@ -148,17 +148,11 @@ add_filter_type(struct event_filter *filter, int id)
if (filter_type)
return filter_type;
- if (!filter->filters)
- filter->event_filters =
- malloc_or_die(sizeof(*filter->event_filters));
- else {
- filter->event_filters =
- realloc(filter->event_filters,
- sizeof(*filter->event_filters) *
- (filter->filters + 1));
- if (!filter->event_filters)
- die("Could not allocate filter");
- }
+ filter->event_filters = realloc(filter->event_filters,
+ sizeof(*filter->event_filters) *
+ (filter->filters + 1));
+ if (!filter->event_filters)
+ die("Could not allocate filter");
for (i = 0; i < filter->filters; i++) {
if (filter->event_filters[i].event_id > id)
@@ -1480,7 +1474,7 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
{
struct filter_type *filter_type;
int count = 0;
- int *ids;
+ int *ids = NULL;
int i;
if (!filter->filters)
@@ -1504,10 +1498,8 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
default:
break;
}
- if (count)
- ids = realloc(ids, sizeof(*ids) * (count + 1));
- else
- ids = malloc(sizeof(*ids));
+
+ ids = realloc(ids, sizeof(*ids) * (count + 1));
if (!ids)
die("Can't allocate ids");
ids[count++] = filter_type->event_id;
@@ -1710,18 +1702,43 @@ static int test_num(struct event_format *event,
static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
{
- const char *val = record->data + arg->str.field->offset;
+ struct event_format *event;
+ struct pevent *pevent;
+ unsigned long long addr;
+ const char *val = NULL;
+ char hex[64];
- /*
- * We need to copy the data since we can't be sure the field
- * is null terminated.
- */
- if (*(val + arg->str.field->size - 1)) {
- /* copy it */
- memcpy(arg->str.buffer, val, arg->str.field->size);
- /* the buffer is already NULL terminated */
- val = arg->str.buffer;
+ /* If the field is not a string convert it */
+ if (arg->str.field->flags & FIELD_IS_STRING) {
+ val = record->data + arg->str.field->offset;
+
+ /*
+ * We need to copy the data since we can't be sure the field
+ * is null terminated.
+ */
+ if (*(val + arg->str.field->size - 1)) {
+ /* copy it */
+ memcpy(arg->str.buffer, val, arg->str.field->size);
+ /* the buffer is already NULL terminated */
+ val = arg->str.buffer;
+ }
+
+ } else {
+ event = arg->str.field->event;
+ pevent = event->pevent;
+ addr = get_value(event, arg->str.field, record);
+
+ if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
+ /* convert to a kernel symbol */
+ val = pevent_find_function(pevent, addr);
+
+ if (val == NULL) {
+ /* just use the hex of the string name */
+ snprintf(hex, 64, "0x%llx", addr);
+ val = hex;
+ }
}
+
return val;
}
@@ -2001,11 +2018,13 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
char *lstr;
char *rstr;
char *op;
- char *str;
+ char *str = NULL;
int len;
lstr = arg_to_str(filter, arg->exp.left);
rstr = arg_to_str(filter, arg->exp.right);
+ if (!lstr || !rstr)
+ goto out;
switch (arg->exp.type) {
case FILTER_EXP_ADD:
@@ -2045,6 +2064,7 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
len = strlen(op) + strlen(lstr) + strlen(rstr) + 4;
str = malloc_or_die(len);
snprintf(str, len, "%s %s %s", lstr, op, rstr);
+out:
free(lstr);
free(rstr);
@@ -2061,6 +2081,8 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
lstr = arg_to_str(filter, arg->num.left);
rstr = arg_to_str(filter, arg->num.right);
+ if (!lstr || !rstr)
+ goto out;
switch (arg->num.type) {
case FILTER_CMP_EQ:
@@ -2097,6 +2119,7 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
break;
}
+out:
free(lstr);
free(rstr);
return str;
@@ -2247,7 +2270,12 @@ int pevent_filter_compare(struct event_filter *filter1, struct event_filter *fil
/* The best way to compare complex filters is with strings */
str1 = arg_to_str(filter1, filter_type1->filter);
str2 = arg_to_str(filter2, filter_type2->filter);
- result = strcmp(str1, str2) != 0;
+ if (str1 && str2)
+ result = strcmp(str1, str2) != 0;
+ else
+ /* bail out if allocation fails */
+ result = 1;
+
free(str1);
free(str2);
if (result)