static struct event_format * update_event(struct pevent *pevent, const char *sys, const char *name, int *id) { struct event_format *event; event = pevent_find_event_by_name(pevent, sys, name); if (!event) return NULL; *id = event->id; return event; }
static int load_events(struct trace_capture *cap, struct tracecmd_xml_handle *handle, struct tracecmd_xml_system_node *node) { struct shark_info *info = cap->info; struct tracecmd_xml_system_node *event_node; struct event_format *event; struct pevent *pevent = cap->pevent; const char *name; int *events = NULL; int event_len = 0; const char *system; const char *event_name; for (node = tracecmd_xml_node_child(node); node; node = tracecmd_xml_node_next(node)) { name = tracecmd_xml_node_type(node); if (strcmp(name, "Event") != 0) continue; event_node = tracecmd_xml_node_child(node); if (!event_node) continue; name = tracecmd_xml_node_type(event_node); if (strcmp(name, "System") != 0) continue; system = tracecmd_xml_node_value(handle, event_node); event_node = tracecmd_xml_node_next(event_node); if (!event_node) continue; name = tracecmd_xml_node_type(event_node); if (strcmp(name, "Name") != 0) continue; event_name = tracecmd_xml_node_value(handle, event_node); event = pevent_find_event_by_name(pevent, system, event_name); if (!event) continue; events = tracecmd_add_id(events, event->id, event_len++); } info->cap_events = events; return 0; }
/** * pevent_update_trivial - update the trivial filters with the given filter * @dest - the filter to update * @source - the filter as the source of the update * @type - the type of trivial filter to update. * * Scan dest for trivial events matching @type to replace with the source. * * Returns 0 on success and -1 if there was a problem updating, but * events may have still been updated on error. */ int pevent_update_trivial(struct event_filter *dest, struct event_filter *source, enum filter_trivial_type type) { struct pevent *src_pevent; struct pevent *dest_pevent; struct event_format *event; struct filter_type *filter_type; struct filter_arg *arg; char *str; int i; src_pevent = source->pevent; dest_pevent = dest->pevent; /* Do nothing if either of the filters has nothing to filter */ if (!dest->filters || !source->filters) return 0; for (i = 0; i < dest->filters; i++) { filter_type = &dest->event_filters[i]; arg = filter_type->filter; if (arg->type != FILTER_ARG_BOOLEAN) continue; if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) || (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE)) continue; event = filter_type->event; if (src_pevent != dest_pevent) { /* do a look up */ event = pevent_find_event_by_name(src_pevent, event->system, event->name); if (!event) return -1; } str = pevent_filter_make_string(source, event->id); if (!str) continue; /* Don't bother if the filter is trivial too */ if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0) filter_event(dest, event, str, NULL); free(str); } return 0; }
static int copy_filter_type(struct event_filter *filter, struct event_filter *source, struct filter_type *filter_type) { struct filter_arg *arg; struct event_format *event; const char *sys; const char *name; char *str; /* Can't assume that the pevent's are the same */ sys = filter_type->event->system; name = filter_type->event->name; event = pevent_find_event_by_name(filter->pevent, sys, name); if (!event) return -1; str = arg_to_str(source, filter_type->filter); if (!str) return -1; if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) { /* Add trivial event */ arg = allocate_arg(); arg->type = FILTER_ARG_BOOLEAN; if (strcmp(str, "TRUE") == 0) arg->boolean.value = 1; else arg->boolean.value = 0; filter_type = add_filter_type(filter, event->id); filter_type->filter = arg; free(str); return 0; } filter_event(filter, event, str, NULL); free(str); return 0; }
int tracecmd_blk_hack(struct tracecmd_input *handle) { struct pevent *pevent; struct event_format *event; struct format_field *field; char buf[4096]; /* way more than enough! */ int id; int l; int r; pevent = tracecmd_get_pevent(handle); /* * Unfortunately, the TRACE_BLK has changed a bit. * We need to test if various events exist to try * to guess what event id TRACE_BLK would be. */ /* It was originally behind the "power" event */ event = pevent_find_event_by_name(pevent, "ftrace", "power"); if (event) { id = event->id + 1; goto found; } /* * But the power tracer is now in perf. * Then it was after kmem_free */ event = pevent_find_event_by_name(pevent, "ftrace", "kmem_free"); if (event) { id = event->id + 1; goto found; } /* * But that then went away. * Currently it should be behind the user stack. */ event = pevent_find_event_by_name(pevent, "ftrace", "user_stack"); if (event) { id = event->id + 1; goto found; } /* Give up :( */ return -1; found: /* * Blk events are not exported in the events directory. * This is a hack to attempt to create a block event * that we can read. * * We'll make a format file to look like this: * * name: blktrace * ID: 13 * format: * field:unsigned short common_type; offset:0; size:2; * field:unsigned char common_flags; offset:2; size:1; * field:unsigned char common_preempt_count; offset:3; size:1; * field:int common_pid; offset:4; size:4; * field:int common_lock_depth; offset:8; size:4; * * field:u64 sector; offset:16; size:8; * field:int bytes; offset:32; size:4; * field:int action; offset:36; size:4; * field:int pid; offset:40; size:4; * field:int device; offset:44; size:4; * field:int cpu; offset:48; size:4; * field:short error; offset:52; size:2; * field:short pdu_len; offset:54; size:2; * field:void data; offset:60; size:0; * * print fmt: "%d", REC->pid * * Note: the struct blk_io_trace is used directly and * just the first parts of the struct are not used in order * to not write over the ftrace data. */ /* Make sure the common fields exist */ field = pevent_find_common_field(event, "common_type"); if (!field || field->offset != 0 || field->size != 2) goto fail; field = pevent_find_common_field(event, "common_flags"); if (!field || field->offset != 2 || field->size != 1) goto fail; field = pevent_find_common_field(event, "common_preempt_count"); if (!field || field->offset != 3 || field->size != 1) goto fail; field = pevent_find_common_field(event, "common_pid"); if (!field || field->offset != 4 || field->size != 4) goto fail; r = sprintf(buf, blk_event_start, id); l = r; /* lock depth is optional */ field = pevent_find_common_field(event, "common_lock_depth"); if (field) { if (field->offset != 8 || field->size != 4) return -1; r = sprintf(buf+l, "\tfield:int common_lock_depth;\toffset:8;\tsize:4;\n"); l += r; } r = sprintf(buf+l, blk_body); /* Parse this event */ l += r; pevent_parse_event(pevent, buf, l, "ftrace"); return 0; fail: return -1; }
static void update_filter_tasks(TraceViewStore *store) { struct tracecmd_input *handle; struct pevent *pevent; struct record *record; gint pid; gint cpu; gint i; handle = store->handle; pevent = tracecmd_get_pevent(store->handle); if (!store->sched_switch_event) { store->sched_switch_event = pevent_find_event_by_name(pevent, "sched", "sched_switch"); if (store->sched_switch_event) store->sched_switch_next_field = pevent_find_any_field(store->sched_switch_event, "next_pid"); store->sched_wakeup_event = pevent_find_event_by_name(pevent, "sched", "sched_wakeup"); if (store->sched_wakeup_event) store->sched_wakeup_pid_field = pevent_find_any_field(store->sched_wakeup_event, "pid"); store->sched_wakeup_new_event = pevent_find_event_by_name(pevent, "sched", "sched_wakeup"); if (store->sched_wakeup_new_event) store->sched_wakeup_new_pid_field = pevent_find_any_field(store->sched_wakeup_new_event, "pid"); } for (cpu = 0; cpu < store->cpus; cpu++) { record = tracecmd_read_cpu_first(handle, cpu); for (i = 0; i < store->cpu_items[cpu]; i++) { g_assert(record->offset == store->cpu_list[cpu][i].offset); /* The record may be filtered by the events */ if (!store->all_events) { int ret; ret = pevent_filter_match(store->event_filter, record); if (ret != FILTER_MATCH) { store->cpu_list[cpu][i].visible = 0; goto skip; } } pid = pevent_data_pid(pevent, record); if (show_task(store, pevent, record, pid)) store->cpu_list[cpu][i].visible = 1; else store->cpu_list[cpu][i].visible = 0; skip: free_record(record); record = tracecmd_read_data(handle, cpu); } g_assert(record == NULL); } merge_sort_rows_ts(store); }