From a5e8e825bd1704c488bf6a46936aaf3b9f203d6a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 8 Apr 2016 11:25:59 -0300 Subject: perf script: Use readdir() instead of deprecated readdir_r() The readdir() function is thread safe as long as just one thread uses a DIR, which is the case in 'perf script', so, to avoid breaking the build with glibc-2.23.90 (upcoming 2.24), use it instead of readdir_r(). See: http://man7.org/linux/man-pages/man3/readdir.3.html "However, in modern implementations (including the glibc implementation), concurrent calls to readdir() that specify different directory streams are thread-safe. In cases where multiple threads must read from the same directory stream, using readdir() with external synchronization is still preferable to the use of the deprecated readdir_r(3) function." Noticed while building on a Fedora Rawhide docker container. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-mt3xz7n2hl49ni2vx7kuq74g@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 70 ++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 36 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 59009aa7e2ca..8f6ab2ac855a 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1415,21 +1415,19 @@ static int is_directory(const char *base_path, const struct dirent *dent) return S_ISDIR(st.st_mode); } -#define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\ - while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ - lang_next) \ - if ((lang_dirent.d_type == DT_DIR || \ - (lang_dirent.d_type == DT_UNKNOWN && \ - is_directory(scripts_path, &lang_dirent))) && \ - (strcmp(lang_dirent.d_name, ".")) && \ - (strcmp(lang_dirent.d_name, ".."))) - -#define for_each_script(lang_path, lang_dir, script_dirent, script_next)\ - while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ - script_next) \ - if (script_dirent.d_type != DT_DIR && \ - (script_dirent.d_type != DT_UNKNOWN || \ - !is_directory(lang_path, &script_dirent))) +#define for_each_lang(scripts_path, scripts_dir, lang_dirent) \ + while ((lang_dirent = readdir(scripts_dir)) != NULL) \ + if ((lang_dirent->d_type == DT_DIR || \ + (lang_dirent->d_type == DT_UNKNOWN && \ + is_directory(scripts_path, lang_dirent))) && \ + (strcmp(lang_dirent->d_name, ".")) && \ + (strcmp(lang_dirent->d_name, ".."))) + +#define for_each_script(lang_path, lang_dir, script_dirent) \ + while ((script_dirent = readdir(lang_dir)) != NULL) \ + if (script_dirent->d_type != DT_DIR && \ + (script_dirent->d_type != DT_UNKNOWN || \ + !is_directory(lang_path, script_dirent))) #define RECORD_SUFFIX "-record" @@ -1575,7 +1573,7 @@ static int list_available_scripts(const struct option *opt __maybe_unused, const char *s __maybe_unused, int unset __maybe_unused) { - struct dirent *script_next, *lang_next, script_dirent, lang_dirent; + struct dirent *script_dirent, *lang_dirent; char scripts_path[MAXPATHLEN]; DIR *scripts_dir, *lang_dir; char script_path[MAXPATHLEN]; @@ -1590,19 +1588,19 @@ static int list_available_scripts(const struct option *opt __maybe_unused, if (!scripts_dir) return -1; - for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { + for_each_lang(scripts_path, scripts_dir, lang_dirent) { snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, - lang_dirent.d_name); + lang_dirent->d_name); lang_dir = opendir(lang_path); if (!lang_dir) continue; - for_each_script(lang_path, lang_dir, script_dirent, script_next) { - script_root = get_script_root(&script_dirent, REPORT_SUFFIX); + for_each_script(lang_path, lang_dir, script_dirent) { + script_root = get_script_root(script_dirent, REPORT_SUFFIX); if (script_root) { desc = script_desc__findnew(script_root); snprintf(script_path, MAXPATHLEN, "%s/%s", - lang_path, script_dirent.d_name); + lang_path, script_dirent->d_name); read_script_info(desc, script_path); free(script_root); } @@ -1690,7 +1688,7 @@ static int check_ev_match(char *dir_name, char *scriptname, */ int find_scripts(char **scripts_array, char **scripts_path_array) { - struct dirent *script_next, *lang_next, script_dirent, lang_dirent; + struct dirent *script_dirent, *lang_dirent; char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; DIR *scripts_dir, *lang_dir; struct perf_session *session; @@ -1713,9 +1711,9 @@ int find_scripts(char **scripts_array, char **scripts_path_array) return -1; } - for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { + for_each_lang(scripts_path, scripts_dir, lang_dirent) { snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, - lang_dirent.d_name); + lang_dirent->d_name); #ifdef NO_LIBPERL if (strstr(lang_path, "perl")) continue; @@ -1729,16 +1727,16 @@ int find_scripts(char **scripts_array, char **scripts_path_array) if (!lang_dir) continue; - for_each_script(lang_path, lang_dir, script_dirent, script_next) { + for_each_script(lang_path, lang_dir, script_dirent) { /* Skip those real time scripts: xxxtop.p[yl] */ - if (strstr(script_dirent.d_name, "top.")) + if (strstr(script_dirent->d_name, "top.")) continue; sprintf(scripts_path_array[i], "%s/%s", lang_path, - script_dirent.d_name); - temp = strchr(script_dirent.d_name, '.'); + script_dirent->d_name); + temp = strchr(script_dirent->d_name, '.'); snprintf(scripts_array[i], - (temp - script_dirent.d_name) + 1, - "%s", script_dirent.d_name); + (temp - script_dirent->d_name) + 1, + "%s", script_dirent->d_name); if (check_ev_match(lang_path, scripts_array[i], session)) @@ -1756,7 +1754,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array) static char *get_script_path(const char *script_root, const char *suffix) { - struct dirent *script_next, *lang_next, script_dirent, lang_dirent; + struct dirent *script_dirent, *lang_dirent; char scripts_path[MAXPATHLEN]; char script_path[MAXPATHLEN]; DIR *scripts_dir, *lang_dir; @@ -1769,21 +1767,21 @@ static char *get_script_path(const char *script_root, const char *suffix) if (!scripts_dir) return NULL; - for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { + for_each_lang(scripts_path, scripts_dir, lang_dirent) { snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, - lang_dirent.d_name); + lang_dirent->d_name); lang_dir = opendir(lang_path); if (!lang_dir) continue; - for_each_script(lang_path, lang_dir, script_dirent, script_next) { - __script_root = get_script_root(&script_dirent, suffix); + for_each_script(lang_path, lang_dir, script_dirent) { + __script_root = get_script_root(script_dirent, suffix); if (__script_root && !strcmp(script_root, __script_root)) { free(__script_root); closedir(lang_dir); closedir(scripts_dir); snprintf(script_path, MAXPATHLEN, "%s/%s", - lang_path, script_dirent.d_name); + lang_path, script_dirent->d_name); return strdup(script_path); } free(__script_root); -- cgit v1.2.3 From 6186de9a491af030889b372193fc9f38c248e69a Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Mon, 11 Apr 2016 10:18:11 -0300 Subject: perf evsel: Allow specifying a file to output in perf_evsel__print_ip As this function will be used in 'perf trace'. Cc: Jiri Olsa Link: http://lkml.kernel.org/n/tip-8x297v9utnxq77onikevvlse@git.kernel.org [ Split from a larger patch ] Signed-off-by: Milian Wolff --- tools/perf/builtin-script.c | 4 ++-- tools/perf/util/session.c | 39 +++++++++++++++++++++------------------ tools/perf/util/session.h | 3 ++- 3 files changed, 25 insertions(+), 21 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8f6ab2ac855a..dbf208f0cdc2 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -580,7 +580,7 @@ static void print_sample_bts(struct perf_sample *sample, } } perf_evsel__print_ip(evsel, sample, al, print_opts, - scripting_max_stack); + scripting_max_stack, stdout); } /* print branch_to information */ @@ -790,7 +790,7 @@ static void process_event(struct perf_script *script, perf_evsel__print_ip(evsel, sample, al, output[attr->type].print_ip_opts, - scripting_max_stack); + scripting_max_stack, stdout); } if (PRINT_FIELD(IREGS)) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index ef370557fb9a..bbac0efbc10c 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1955,7 +1955,8 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, struct addr_location *al, - unsigned int print_opts, unsigned int stack_depth) + unsigned int print_opts, unsigned int stack_depth, + FILE *fp) { struct callchain_cursor_node *node; int print_ip = print_opts & PRINT_IP_OPT_IP; @@ -1992,33 +1993,35 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, goto next; if (print_ip) - printf("%c%16" PRIx64, s, node->ip); + fprintf(fp, "%c%16" PRIx64, s, node->ip); if (node->map) addr = node->map->map_ip(node->map, node->ip); if (print_sym) { - printf(" "); + fprintf(fp, " "); if (print_symoffset) { node_al.addr = addr; node_al.map = node->map; - symbol__fprintf_symname_offs(node->sym, &node_al, stdout); + symbol__fprintf_symname_offs(node->sym, + &node_al, + fp); } else - symbol__fprintf_symname(node->sym, stdout); + symbol__fprintf_symname(node->sym, fp); } if (print_dso) { - printf(" ("); - map__fprintf_dsoname(node->map, stdout); - printf(")"); + fprintf(fp, " ("); + map__fprintf_dsoname(node->map, fp); + fprintf(fp, ")"); } if (print_srcline) map__fprintf_srcline(node->map, addr, "\n ", - stdout); + fp); if (!print_oneline) - printf("\n"); + fprintf(fp, "\n"); stack_depth--; next: @@ -2030,25 +2033,25 @@ next: return; if (print_ip) - printf("%16" PRIx64, sample->ip); + fprintf(fp, "%16" PRIx64, sample->ip); if (print_sym) { - printf(" "); + fprintf(fp, " "); if (print_symoffset) symbol__fprintf_symname_offs(al->sym, al, - stdout); + fp); else - symbol__fprintf_symname(al->sym, stdout); + symbol__fprintf_symname(al->sym, fp); } if (print_dso) { - printf(" ("); - map__fprintf_dsoname(al->map, stdout); - printf(")"); + fprintf(fp, " ("); + map__fprintf_dsoname(al->map, fp); + fprintf(fp, ")"); } if (print_srcline) - map__fprintf_srcline(al->map, al->addr, "\n ", stdout); + map__fprintf_srcline(al->map, al->addr, "\n ", fp); } } diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index f96fc9e8c52e..0ee3d9dbc099 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -106,7 +106,8 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, struct addr_location *al, - unsigned int print_opts, unsigned int stack_depth); + unsigned int print_opts, unsigned int stack_depth, + FILE *fp); int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap); -- cgit v1.2.3 From db3617f362d7e205621c1ccc22b77d224a81ee14 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 11 Apr 2016 10:53:51 -0300 Subject: perf evsel: Allow passing a left alignment when printing a symbol For callchains, etc where we want it to align just below the syscall name, for instance, in 'perf trace' Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-uk9ekchd67651c625ltaur5y@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 4 ++-- tools/perf/util/session.c | 6 +++++- tools/perf/util/session.h | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index dbf208f0cdc2..60fde9f5025c 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -579,7 +579,7 @@ static void print_sample_bts(struct perf_sample *sample, print_opts &= ~PRINT_IP_OPT_SRCLINE; } } - perf_evsel__print_ip(evsel, sample, al, print_opts, + perf_evsel__print_ip(evsel, sample, al, 0, print_opts, scripting_max_stack, stdout); } @@ -788,7 +788,7 @@ static void process_event(struct perf_script *script, else printf("\n"); - perf_evsel__print_ip(evsel, sample, al, + perf_evsel__print_ip(evsel, sample, al, 0, output[attr->type].print_ip_opts, scripting_max_stack, stdout); } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index bbac0efbc10c..62b6d4051b99 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1954,7 +1954,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, } void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, - struct addr_location *al, + struct addr_location *al, int left_alignment, unsigned int print_opts, unsigned int stack_depth, FILE *fp) { @@ -1992,6 +1992,8 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, if (node->sym && node->sym->ignore) goto next; + fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); + if (print_ip) fprintf(fp, "%c%16" PRIx64, s, node->ip); @@ -2032,6 +2034,8 @@ next: if (al->sym && al->sym->ignore) return; + fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); + if (print_ip) fprintf(fp, "%16" PRIx64, sample->ip); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 0ee3d9dbc099..a6bc4ddbae3e 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -105,7 +105,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, unsigned int type); void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, - struct addr_location *al, + struct addr_location *al, int left_alignment, unsigned int print_opts, unsigned int stack_depth, FILE *fp); -- cgit v1.2.3 From ff0c107806cf9d237e50e21de66d6909391071cd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 11 Apr 2016 11:14:06 -0300 Subject: perf evsel: Rename print_ip() to fprintf_sym() As it receives a FILE, and its more than just the IP, which can even be requested not to be printed. For consistency with other similar methods in tools/perf/, name it as perf_evsel__fprintf_sym() and make it return the number of bytes printed, just like 'fprintf(3)' Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Milian Wolff Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-84gawlqa3lhk63nf0t9vnqnn@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 10 ++++---- tools/perf/builtin-trace.c | 4 +-- tools/perf/util/session.c | 60 +++++++++++++++++++++------------------------ tools/perf/util/session.h | 8 +++--- 4 files changed, 39 insertions(+), 43 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 60fde9f5025c..ddd5b79e94c2 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -579,8 +579,8 @@ static void print_sample_bts(struct perf_sample *sample, print_opts &= ~PRINT_IP_OPT_SRCLINE; } } - perf_evsel__print_ip(evsel, sample, al, 0, print_opts, - scripting_max_stack, stdout); + perf_evsel__fprintf_sym(evsel, sample, al, 0, print_opts, + scripting_max_stack, stdout); } /* print branch_to information */ @@ -788,9 +788,9 @@ static void process_event(struct perf_script *script, else printf("\n"); - perf_evsel__print_ip(evsel, sample, al, 0, - output[attr->type].print_ip_opts, - scripting_max_stack, stdout); + perf_evsel__fprintf_sym(evsel, sample, al, 0, + output[attr->type].print_ip_opts, + scripting_max_stack, stdout); } if (PRINT_FIELD(IREGS)) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8c587a8d3742..a0d5c680c39e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2203,8 +2203,8 @@ signed_print: event->header.type); goto out_put; } - perf_evsel__print_ip(evsel, sample, &al, 38, print_opts, - scripting_max_stack, trace->output); + perf_evsel__fprintf_sym(evsel, sample, &al, 38, print_opts, + scripting_max_stack, trace->output); } out: ttrace->entry_pending = false; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 62b6d4051b99..0669a088ea0d 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1953,11 +1953,12 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, return NULL; } -void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, - struct addr_location *al, int left_alignment, - unsigned int print_opts, unsigned int stack_depth, - FILE *fp) +int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample, + struct addr_location *al, int left_alignment, + unsigned int print_opts, unsigned int stack_depth, + FILE *fp) { + int printed = 0; struct callchain_cursor_node *node; int print_ip = print_opts & PRINT_IP_OPT_IP; int print_sym = print_opts & PRINT_IP_OPT_SYM; @@ -1975,7 +1976,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, stack_depth) != 0) { if (verbose) error("Failed to resolve callchain. Skipping\n"); - return; + return printed; } callchain_cursor_commit(&callchain_cursor); @@ -1992,71 +1993,66 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, if (node->sym && node->sym->ignore) goto next; - fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); + printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); if (print_ip) - fprintf(fp, "%c%16" PRIx64, s, node->ip); + printed += fprintf(fp, "%c%16" PRIx64, s, node->ip); if (node->map) addr = node->map->map_ip(node->map, node->ip); if (print_sym) { - fprintf(fp, " "); + printed += fprintf(fp, " "); if (print_symoffset) { node_al.addr = addr; node_al.map = node->map; - symbol__fprintf_symname_offs(node->sym, - &node_al, - fp); + printed += symbol__fprintf_symname_offs(node->sym, &node_al, fp); } else - symbol__fprintf_symname(node->sym, fp); + printed += symbol__fprintf_symname(node->sym, fp); } if (print_dso) { - fprintf(fp, " ("); - map__fprintf_dsoname(node->map, fp); - fprintf(fp, ")"); + printed += fprintf(fp, " ("); + printed += map__fprintf_dsoname(node->map, fp); + printed += fprintf(fp, ")"); } if (print_srcline) - map__fprintf_srcline(node->map, addr, "\n ", - fp); + printed += map__fprintf_srcline(node->map, addr, "\n ", fp); if (!print_oneline) - fprintf(fp, "\n"); + printed += fprintf(fp, "\n"); stack_depth--; next: callchain_cursor_advance(&callchain_cursor); } - } else { - if (al->sym && al->sym->ignore) - return; - - fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); + } else if (!(al->sym && al->sym->ignore)) { + printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); if (print_ip) - fprintf(fp, "%16" PRIx64, sample->ip); + printed += fprintf(fp, "%16" PRIx64, sample->ip); if (print_sym) { - fprintf(fp, " "); + printed += fprintf(fp, " "); if (print_symoffset) - symbol__fprintf_symname_offs(al->sym, al, - fp); + printed += symbol__fprintf_symname_offs(al->sym, al, fp); else - symbol__fprintf_symname(al->sym, fp); + printed += symbol__fprintf_symname(al->sym, fp); } if (print_dso) { - fprintf(fp, " ("); - map__fprintf_dsoname(al->map, fp); - fprintf(fp, ")"); + printed += fprintf(fp, " ("); + printed += map__fprintf_dsoname(al->map, fp); + printed += fprintf(fp, ")"); } if (print_srcline) - map__fprintf_srcline(al->map, al->addr, "\n ", fp); + printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp); } + + return printed; } int perf_session__cpu_bitmap(struct perf_session *session, diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index a6bc4ddbae3e..ac834908bb35 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -104,10 +104,10 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, unsigned int type); -void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, - struct addr_location *al, int left_alignment, - unsigned int print_opts, unsigned int stack_depth, - FILE *fp); +int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample, + struct addr_location *al, int left_alignment, + unsigned int print_opts, unsigned int stack_depth, + FILE *fp); int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap); -- cgit v1.2.3