aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/trace-cmd-report.1.txt8
-rw-r--r--parse-filter.c75
2 files changed, 65 insertions, 18 deletions
diff --git a/Documentation/trace-cmd-report.1.txt b/Documentation/trace-cmd-report.1.txt
index fbab3f4..86169f2 100644
--- a/Documentation/trace-cmd-report.1.txt
+++ b/Documentation/trace-cmd-report.1.txt
@@ -98,6 +98,14 @@ OPTIONS
98 98
99 Although the output displays 'R', having 'prev_stat=="R"' will not work. 99 Although the output displays 'R', having 'prev_stat=="R"' will not work.
100 100
101 Note: You can also specify 'COMM' as an EVENT_FIELD. This will use the
102 task name (or comm) of the record to compare. For example, to filter out
103 all of the "trace-cmd" tasks:
104
105------------------------------------------
106 -F '.*:COMM != "trace-cmd"'
107------------------------------------------
108
101*-v*:: 109*-v*::
102 This causes the following filters of *-F* to filter out the matching 110 This causes the following filters of *-F* to filter out the matching
103 events. 111 events.
diff --git a/parse-filter.c b/parse-filter.c
index 75512e3..eb2ef6d 100644
--- a/parse-filter.c
+++ b/parse-filter.c
@@ -28,6 +28,12 @@
28#include "parse-events.h" 28#include "parse-events.h"
29#include "util.h" 29#include "util.h"
30 30
31#define COMM "COMM"
32
33static struct format_field comm = {
34 .name = "COMM",
35};
36
31struct event_list { 37struct event_list {
32 struct event_list *next; 38 struct event_list *next;
33 struct event_format *event; 39 struct event_format *event;
@@ -539,13 +545,18 @@ process_value_token(struct event_format *event, struct filter_arg **parg,
539 } 545 }
540 /* Consider this a field */ 546 /* Consider this a field */
541 field = pevent_find_any_field(event, token); 547 field = pevent_find_any_field(event, token);
542 free_token(token);
543 if (!field) { 548 if (!field) {
544 /* not a field, so NULL it up */ 549 if (strcmp(token, COMM) != 0) {
545 free_arg(arg); 550 /* not a field, so NULL it up */
546 arg = NULL; 551 free_token(token);
547 break; 552 free_arg(arg);
553 arg = NULL;
554 break;
555 }
556 /* If token is 'COMM' then it is special */
557 field = &comm;
548 } 558 }
559 free_token(token);
549 560
550 arg->type = FILTER_ARG_FIELD; 561 arg->type = FILTER_ARG_FIELD;
551 arg->field.field = field; 562 arg->field.field = field;
@@ -1414,11 +1425,31 @@ int pevent_filter_event_has_trivial(struct event_filter *filter,
1414static int test_filter(struct event_format *event, 1425static int test_filter(struct event_format *event,
1415 struct filter_arg *arg, struct record *record); 1426 struct filter_arg *arg, struct record *record);
1416 1427
1428static const char *
1429get_comm(struct event_format *event, struct record *record)
1430{
1431 const char *comm;
1432 int pid;
1433
1434 pid = pevent_data_pid(event->pevent, record);
1435 comm = pevent_data_comm_from_pid(event->pevent, pid);
1436 return comm;
1437}
1438
1417static unsigned long long 1439static unsigned long long
1418get_value(struct format_field *field, struct record *record) 1440get_value(struct event_format *event,
1441 struct format_field *field, struct record *record)
1419{ 1442{
1420 unsigned long long val; 1443 unsigned long long val;
1421 1444
1445 /* Handle our dummy "comm" field */
1446 if (field == &comm) {
1447 const char *name;
1448
1449 name = get_comm(event, record);
1450 return (unsigned long long)name;
1451 }
1452
1422 pevent_read_number_field(field, record->data, &val); 1453 pevent_read_number_field(field, record->data, &val);
1423 1454
1424 if (!(field->flags & FIELD_IS_SIGNED)) 1455 if (!(field->flags & FIELD_IS_SIGNED))
@@ -1491,7 +1522,7 @@ get_arg_value(struct event_format *event, struct filter_arg *arg, struct record
1491{ 1522{
1492 switch (arg->type) { 1523 switch (arg->type) {
1493 case FILTER_ARG_FIELD: 1524 case FILTER_ARG_FIELD:
1494 return get_value(arg->field.field, record); 1525 return get_value(event, arg->field.field, record);
1495 1526
1496 case FILTER_ARG_VALUE: 1527 case FILTER_ARG_VALUE:
1497 if (arg->value.type != FILTER_NUMBER) 1528 if (arg->value.type != FILTER_NUMBER)
@@ -1540,11 +1571,9 @@ static int test_num(struct event_format *event,
1540 } 1571 }
1541} 1572}
1542 1573
1543static int test_str(struct event_format *event, 1574static const char *get_field_str(struct filter_arg *arg, struct record *record)
1544 struct filter_arg *arg, struct record *record)
1545{ 1575{
1546 const char *val = record->data + arg->str.field->offset; 1576 const char *val = record->data + arg->str.field->offset;
1547 const char *buffer;
1548 1577
1549 /* 1578 /*
1550 * We need to copy the data since we can't be sure the field 1579 * We need to copy the data since we can't be sure the field
@@ -1554,24 +1583,34 @@ static int test_str(struct event_format *event,
1554 /* copy it */ 1583 /* copy it */
1555 memcpy(arg->str.buffer, val, arg->str.field->size); 1584 memcpy(arg->str.buffer, val, arg->str.field->size);
1556 /* the buffer is already NULL terminated */ 1585 /* the buffer is already NULL terminated */
1557 buffer = arg->str.buffer; 1586 val = arg->str.buffer;
1558 } else 1587 }
1559 /* OK, it's NULL terminated */ 1588 return val;
1560 buffer = val; 1589}
1590
1591static int test_str(struct event_format *event,
1592 struct filter_arg *arg, struct record *record)
1593{
1594 const char *val;
1595
1596 if (arg->str.field == &comm)
1597 val = get_comm(event, record);
1598 else
1599 val = get_field_str(arg, record);
1561 1600
1562 switch (arg->str.type) { 1601 switch (arg->str.type) {
1563 case FILTER_CMP_MATCH: 1602 case FILTER_CMP_MATCH:
1564 return strcmp(buffer, arg->str.val) == 0; 1603 return strcmp(val, arg->str.val) == 0;
1565 1604
1566 case FILTER_CMP_NOT_MATCH: 1605 case FILTER_CMP_NOT_MATCH:
1567 return strcmp(buffer, arg->str.val) != 0; 1606 return strcmp(val, arg->str.val) != 0;
1568 1607
1569 case FILTER_CMP_REGEX: 1608 case FILTER_CMP_REGEX:
1570 /* Returns zero on match */ 1609 /* Returns zero on match */
1571 return !regexec(&arg->str.reg, buffer, 0, NULL, 0); 1610 return !regexec(&arg->str.reg, val, 0, NULL, 0);
1572 1611
1573 case FILTER_CMP_NOT_REGEX: 1612 case FILTER_CMP_NOT_REGEX:
1574 return regexec(&arg->str.reg, buffer, 0, NULL, 0); 1613 return regexec(&arg->str.reg, val, 0, NULL, 0);
1575 1614
1576 default: 1615 default:
1577 /* ?? */ 1616 /* ?? */