static int add_tracepoint_multi_sys(char *sys_name, char *evt_name) { struct dirent *events_ent; DIR *events_dir; int ret = 0; events_dir = opendir(TRACING_EVENTS_DIR); if (!events_dir) { perror("Can't open event dir"); return -1; } while (!ret && (events_ent = readdir(events_dir))) { if (!strcmp(events_ent->d_name, ".") || !strcmp(events_ent->d_name, "..") || !strcmp(events_ent->d_name, "enable") || !strcmp(events_ent->d_name, "header_event") || !strcmp(events_ent->d_name, "header_page")) continue; if (!strglobmatch(events_ent->d_name, sys_name)) continue; ret = add_tracepoint_event(events_ent->d_name, evt_name); } closedir(events_dir); return ret; }
static int add_tracepoint_multi_event(char *sys_name, char *evt_name) { char evt_path[PATH_MAX]; struct dirent *evt_ent; DIR *evt_dir; int ret = 0; snprintf(evt_path, PATH_MAX, "%s/%s", TRACING_EVENTS_DIR, sys_name); evt_dir = opendir(evt_path); if (!evt_dir) { perror("Can't open event dir"); return -1; } while (!ret && (evt_ent = readdir(evt_dir))) { if (!strcmp(evt_ent->d_name, ".") || !strcmp(evt_ent->d_name, "..") || !strcmp(evt_ent->d_name, "enable") || !strcmp(evt_ent->d_name, "filter")) continue; if (!strglobmatch(evt_ent->d_name, evt_name)) continue; ret = add_tracepoint(sys_name, evt_ent->d_name); } closedir(evt_dir); return ret; }
/** * die_match_name - Match diename and glob * @dw_die: a DIE * @glob: a string of target glob pattern * * Glob matching the name of @dw_die and @glob. Return false if matching fail. */ bool die_match_name(Dwarf_Die *dw_die, const char *glob) { const char *name; name = dwarf_diename(dw_die); return name ? strglobmatch(name, glob) : false; }
int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx) { int i; struct syscall *syscalls = tbl->syscalls.entries; for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) { if (strglobmatch(syscalls[i].name, syscall_glob)) { *idx = i; return syscalls[i].id; } } return -1; }
unsigned long find_kernel_symbol(const char *symbol) { int ret; struct ksym_addr_t arg = { .name = symbol, .addr = 0 }; ret = kallsyms_parse(&arg, symbol_cmp); if (ret < 0 || arg.addr == 0) { fprintf(stderr, "cannot read kernel symbol \"%s\" in %s\n", symbol, KALLSYMS_PATH); exit(EXIT_FAILURE); } return arg.addr; } #define AVAILABLE_EVENTS_PATH "/sys/kernel/debug/tracing/available_events" void list_available_events(const char *match) { FILE *file; char *line = NULL; file = fopen(AVAILABLE_EVENTS_PATH, "r"); if (file == NULL) handle_error("open " AVAILABLE_EVENTS_PATH " failed"); while (!feof(file)) { int line_len; size_t n; line_len = getline(&line, &n, file); if (line_len < 0 || !line) break; if (!match || strglobmatch(line, match)) printf("%s", line); } free(line); fclose(file); }
static int kprobe_symbol_actor(void *arg, const char *name, char type, unsigned long start) { struct probe_cb_base *base = (struct probe_cb_base *)arg; /* only can probe text function */ if (type != 't' && type != 'T') return 0; if (!strglobmatch(name, base->symbol)) return 0; if (check_kprobe_addr_prohibited(start)) return 0; return write_kprobe_event(base->fd, base->ret_probe, name, base->fetch_args); }
static bool strfilter_node__compare(struct strfilter_node *self, const char *str) { if (!self || !self->p) return false; switch (*self->p) { case '|': /* */ return strfilter_node__compare(self->l, str) || strfilter_node__compare(self->r, str); case '&': /* */ return strfilter_node__compare(self->l, str) && strfilter_node__compare(self->r, str); case '!': /* */ return !strfilter_node__compare(self->r, str); default: return strglobmatch(str, self->p); } }
static int uprobe_symbol_actor(const char *name, vaddr_t addr, void *arg) { struct probe_cb_base *base = (struct probe_cb_base *)arg; int ret; if (!strglobmatch(name, base->symbol)) return 0; verbose_printf("uprobe: binary: \"%s\" symbol \"%s\" " "resolved to 0x%lx\n", base->binary, base->symbol, addr); ret = write_uprobe_event(base->fd, base->ret_probe, base->binary, name, addr, base->fetch_args); if (ret) return ret; return 0; }
static bool strfilter_node__compare(struct strfilter_node *node, const char *str) { if (!node || !node->p) return false; switch (*node->p) { case '|': /* OR */ return strfilter_node__compare(node->l, str) || strfilter_node__compare(node->r, str); case '&': /* AND */ return strfilter_node__compare(node->l, str) && strfilter_node__compare(node->r, str); case '!': /* NOT */ return !strfilter_node__compare(node->r, str); default: return strglobmatch(str, node->p); } }
void process_available_tracepoints(const char *sys, const char *event, int (*process)(const char *sys, const char *event)) { char *line = NULL; FILE *file; char str[128] = {0}; /* add '\n' into tail */ snprintf(str, 64, "%s:%s\n", sys, event); file = fopen(AVAILABLE_EVENTS_PATH, "r"); if (file == NULL) handle_error("open " AVAILABLE_EVENTS_PATH " failed"); while (!feof(file)) { int line_len; size_t n; line_len = getline(&line, &n, file); if (line_len < 0 || !line) break; if (strglobmatch(line, str)) { char match_sys[64] = {0}; char match_event[64] = {0}; char *sep; sep = strchr(line, ':'); memcpy(match_sys, line, sep - line); memcpy(match_event, sep + 1, line_len - (sep - line) - 2); if (process(match_sys, match_event)) break; } } free(line); fclose(file); }