diff options
62 files changed, 739 insertions, 208 deletions
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index 143d98df2df9..f709de54707b 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt | |||
| @@ -8,7 +8,7 @@ perf-list - List all symbolic event types | |||
| 8 | SYNOPSIS | 8 | SYNOPSIS |
| 9 | -------- | 9 | -------- |
| 10 | [verse] | 10 | [verse] |
| 11 | 'perf list' [--no-desc] [--long-desc] [hw|sw|cache|tracepoint|pmu|event_glob] | 11 | 'perf list' [--no-desc] [--long-desc] [hw|sw|cache|tracepoint|pmu|sdt|event_glob] |
| 12 | 12 | ||
| 13 | DESCRIPTION | 13 | DESCRIPTION |
| 14 | ----------- | 14 | ----------- |
| @@ -244,6 +244,8 @@ To limit the list use: | |||
| 244 | 244 | ||
| 245 | . 'pmu' to print the kernel supplied PMU events. | 245 | . 'pmu' to print the kernel supplied PMU events. |
| 246 | 246 | ||
| 247 | . 'sdt' to list all Statically Defined Tracepoint events. | ||
| 248 | |||
| 247 | . If none of the above is matched, it will apply the supplied glob to all | 249 | . If none of the above is matched, it will apply the supplied glob to all |
| 248 | events, printing the ones that match. | 250 | events, printing the ones that match. |
| 249 | 251 | ||
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index e9a61f5485eb..37a175914157 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt | |||
| @@ -235,6 +235,7 @@ OPTIONS | |||
| 235 | sort_key can be: | 235 | sort_key can be: |
| 236 | - function: compare on functions (default) | 236 | - function: compare on functions (default) |
| 237 | - address: compare on individual code addresses | 237 | - address: compare on individual code addresses |
| 238 | - srcline: compare on source filename and line number | ||
| 238 | 239 | ||
| 239 | branch can be: | 240 | branch can be: |
| 240 | - branch: include last branch information in callgraph when available. | 241 | - branch: include last branch information in callgraph when available. |
| @@ -430,6 +431,10 @@ include::itrace.txt[] | |||
| 430 | --hierarchy:: | 431 | --hierarchy:: |
| 431 | Enable hierarchical output. | 432 | Enable hierarchical output. |
| 432 | 433 | ||
| 434 | --inline:: | ||
| 435 | If a callgraph address belongs to an inlined function, the inline stack | ||
| 436 | will be printed. Each entry is function name or file/line. | ||
| 437 | |||
| 433 | include::callchain-overhead-calculation.txt[] | 438 | include::callchain-overhead-calculation.txt[] |
| 434 | 439 | ||
| 435 | SEE ALSO | 440 | SEE ALSO |
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h index 579a592990dd..842ab2781cdc 100644 --- a/tools/perf/bench/bench.h +++ b/tools/perf/bench/bench.h | |||
| @@ -25,17 +25,17 @@ | |||
| 25 | # endif | 25 | # endif |
| 26 | #endif | 26 | #endif |
| 27 | 27 | ||
| 28 | int bench_numa(int argc, const char **argv, const char *prefix); | 28 | int bench_numa(int argc, const char **argv); |
| 29 | int bench_sched_messaging(int argc, const char **argv, const char *prefix); | 29 | int bench_sched_messaging(int argc, const char **argv); |
| 30 | int bench_sched_pipe(int argc, const char **argv, const char *prefix); | 30 | int bench_sched_pipe(int argc, const char **argv); |
| 31 | int bench_mem_memcpy(int argc, const char **argv, const char *prefix); | 31 | int bench_mem_memcpy(int argc, const char **argv); |
| 32 | int bench_mem_memset(int argc, const char **argv, const char *prefix); | 32 | int bench_mem_memset(int argc, const char **argv); |
| 33 | int bench_futex_hash(int argc, const char **argv, const char *prefix); | 33 | int bench_futex_hash(int argc, const char **argv); |
| 34 | int bench_futex_wake(int argc, const char **argv, const char *prefix); | 34 | int bench_futex_wake(int argc, const char **argv); |
| 35 | int bench_futex_wake_parallel(int argc, const char **argv, const char *prefix); | 35 | int bench_futex_wake_parallel(int argc, const char **argv); |
| 36 | int bench_futex_requeue(int argc, const char **argv, const char *prefix); | 36 | int bench_futex_requeue(int argc, const char **argv); |
| 37 | /* pi futexes */ | 37 | /* pi futexes */ |
| 38 | int bench_futex_lock_pi(int argc, const char **argv, const char *prefix); | 38 | int bench_futex_lock_pi(int argc, const char **argv); |
| 39 | 39 | ||
| 40 | #define BENCH_FORMAT_DEFAULT_STR "default" | 40 | #define BENCH_FORMAT_DEFAULT_STR "default" |
| 41 | #define BENCH_FORMAT_DEFAULT 0 | 41 | #define BENCH_FORMAT_DEFAULT 0 |
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index 2499e1b0c6fb..fe16b310097f 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c | |||
| @@ -114,8 +114,7 @@ static void print_summary(void) | |||
| 114 | (int) runtime.tv_sec); | 114 | (int) runtime.tv_sec); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | int bench_futex_hash(int argc, const char **argv, | 117 | int bench_futex_hash(int argc, const char **argv) |
| 118 | const char *prefix __maybe_unused) | ||
| 119 | { | 118 | { |
| 120 | int ret = 0; | 119 | int ret = 0; |
| 121 | cpu_set_t cpu; | 120 | cpu_set_t cpu; |
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index a20814d94af1..73a1c44ea63c 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c | |||
| @@ -140,8 +140,7 @@ static void create_threads(struct worker *w, pthread_attr_t thread_attr) | |||
| 140 | } | 140 | } |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | int bench_futex_lock_pi(int argc, const char **argv, | 143 | int bench_futex_lock_pi(int argc, const char **argv) |
| 144 | const char *prefix __maybe_unused) | ||
| 145 | { | 144 | { |
| 146 | int ret = 0; | 145 | int ret = 0; |
| 147 | unsigned int i; | 146 | unsigned int i; |
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 9fad1e4fcd3e..41786cbea24c 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c | |||
| @@ -109,8 +109,7 @@ static void toggle_done(int sig __maybe_unused, | |||
| 109 | done = true; | 109 | done = true; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | int bench_futex_requeue(int argc, const char **argv, | 112 | int bench_futex_requeue(int argc, const char **argv) |
| 113 | const char *prefix __maybe_unused) | ||
| 114 | { | 113 | { |
| 115 | int ret = 0; | 114 | int ret = 0; |
| 116 | unsigned int i, j; | 115 | unsigned int i, j; |
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index 40f5fcf1d120..4ab12c8e016a 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c | |||
| @@ -197,8 +197,7 @@ static void toggle_done(int sig __maybe_unused, | |||
| 197 | done = true; | 197 | done = true; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | int bench_futex_wake_parallel(int argc, const char **argv, | 200 | int bench_futex_wake_parallel(int argc, const char **argv) |
| 201 | const char *prefix __maybe_unused) | ||
| 202 | { | 201 | { |
| 203 | int ret = 0; | 202 | int ret = 0; |
| 204 | unsigned int i, j; | 203 | unsigned int i, j; |
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 789490281ae3..2fa49222ef8d 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c | |||
| @@ -115,8 +115,7 @@ static void toggle_done(int sig __maybe_unused, | |||
| 115 | done = true; | 115 | done = true; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | int bench_futex_wake(int argc, const char **argv, | 118 | int bench_futex_wake(int argc, const char **argv) |
| 119 | const char *prefix __maybe_unused) | ||
| 120 | { | 119 | { |
| 121 | int ret = 0; | 120 | int ret = 0; |
| 122 | unsigned int i, j; | 121 | unsigned int i, j; |
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c index 52504a83b5a1..d1dea33dcfcf 100644 --- a/tools/perf/bench/mem-functions.c +++ b/tools/perf/bench/mem-functions.c | |||
| @@ -284,7 +284,7 @@ static const char * const bench_mem_memcpy_usage[] = { | |||
| 284 | NULL | 284 | NULL |
| 285 | }; | 285 | }; |
| 286 | 286 | ||
| 287 | int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused) | 287 | int bench_mem_memcpy(int argc, const char **argv) |
| 288 | { | 288 | { |
| 289 | struct bench_mem_info info = { | 289 | struct bench_mem_info info = { |
| 290 | .functions = memcpy_functions, | 290 | .functions = memcpy_functions, |
| @@ -358,7 +358,7 @@ static const struct function memset_functions[] = { | |||
| 358 | { .name = NULL, } | 358 | { .name = NULL, } |
| 359 | }; | 359 | }; |
| 360 | 360 | ||
| 361 | int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused) | 361 | int bench_mem_memset(int argc, const char **argv) |
| 362 | { | 362 | { |
| 363 | struct bench_mem_info info = { | 363 | struct bench_mem_info info = { |
| 364 | .functions = memset_functions, | 364 | .functions = memset_functions, |
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 6bd0581de298..1fe43bd5a012 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c | |||
| @@ -1767,7 +1767,7 @@ static int bench_all(void) | |||
| 1767 | return 0; | 1767 | return 0; |
| 1768 | } | 1768 | } |
| 1769 | 1769 | ||
| 1770 | int bench_numa(int argc, const char **argv, const char *prefix __maybe_unused) | 1770 | int bench_numa(int argc, const char **argv) |
| 1771 | { | 1771 | { |
| 1772 | init_params(&p0, "main,", argc, argv); | 1772 | init_params(&p0, "main,", argc, argv); |
| 1773 | argc = parse_options(argc, argv, options, bench_numa_usage, 0); | 1773 | argc = parse_options(argc, argv, options, bench_numa_usage, 0); |
diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c index 6a111e775210..4f961e74535b 100644 --- a/tools/perf/bench/sched-messaging.c +++ b/tools/perf/bench/sched-messaging.c | |||
| @@ -260,8 +260,7 @@ static const char * const bench_sched_message_usage[] = { | |||
| 260 | NULL | 260 | NULL |
| 261 | }; | 261 | }; |
| 262 | 262 | ||
| 263 | int bench_sched_messaging(int argc, const char **argv, | 263 | int bench_sched_messaging(int argc, const char **argv) |
| 264 | const char *prefix __maybe_unused) | ||
| 265 | { | 264 | { |
| 266 | unsigned int i, total_children; | 265 | unsigned int i, total_children; |
| 267 | struct timeval start, stop, diff; | 266 | struct timeval start, stop, diff; |
diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index 2243f0150d76..a152737370c5 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c | |||
| @@ -76,7 +76,7 @@ static void *worker_thread(void *__tdata) | |||
| 76 | return NULL; | 76 | return NULL; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | int bench_sched_pipe(int argc, const char **argv, const char *prefix __maybe_unused) | 79 | int bench_sched_pipe(int argc, const char **argv) |
| 80 | { | 80 | { |
| 81 | struct thread_data threads[2], *td; | 81 | struct thread_data threads[2], *td; |
| 82 | int pipe_1[2], pipe_2[2]; | 82 | int pipe_1[2], pipe_2[2]; |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index e54b1f9fe1ee..56a7c8d210b9 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -383,7 +383,7 @@ static const char * const annotate_usage[] = { | |||
| 383 | NULL | 383 | NULL |
| 384 | }; | 384 | }; |
| 385 | 385 | ||
| 386 | int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) | 386 | int cmd_annotate(int argc, const char **argv) |
| 387 | { | 387 | { |
| 388 | struct perf_annotate annotate = { | 388 | struct perf_annotate annotate = { |
| 389 | .tool = { | 389 | .tool = { |
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index a1cddc6bbf0f..445e62881254 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | #include <string.h> | 25 | #include <string.h> |
| 26 | #include <sys/prctl.h> | 26 | #include <sys/prctl.h> |
| 27 | 27 | ||
| 28 | typedef int (*bench_fn_t)(int argc, const char **argv, const char *prefix); | 28 | typedef int (*bench_fn_t)(int argc, const char **argv); |
| 29 | 29 | ||
| 30 | struct bench { | 30 | struct bench { |
| 31 | const char *name; | 31 | const char *name; |
| @@ -155,7 +155,7 @@ static int bench_str2int(const char *str) | |||
| 155 | * to something meaningful: | 155 | * to something meaningful: |
| 156 | */ | 156 | */ |
| 157 | static int run_bench(const char *coll_name, const char *bench_name, bench_fn_t fn, | 157 | static int run_bench(const char *coll_name, const char *bench_name, bench_fn_t fn, |
| 158 | int argc, const char **argv, const char *prefix) | 158 | int argc, const char **argv) |
| 159 | { | 159 | { |
| 160 | int size; | 160 | int size; |
| 161 | char *name; | 161 | char *name; |
| @@ -171,7 +171,7 @@ static int run_bench(const char *coll_name, const char *bench_name, bench_fn_t f | |||
| 171 | prctl(PR_SET_NAME, name); | 171 | prctl(PR_SET_NAME, name); |
| 172 | argv[0] = name; | 172 | argv[0] = name; |
| 173 | 173 | ||
| 174 | ret = fn(argc, argv, prefix); | 174 | ret = fn(argc, argv); |
| 175 | 175 | ||
| 176 | free(name); | 176 | free(name); |
| 177 | 177 | ||
| @@ -198,7 +198,7 @@ static void run_collection(struct collection *coll) | |||
| 198 | fflush(stdout); | 198 | fflush(stdout); |
| 199 | 199 | ||
| 200 | argv[1] = bench->name; | 200 | argv[1] = bench->name; |
| 201 | run_bench(coll->name, bench->name, bench->fn, 1, argv, NULL); | 201 | run_bench(coll->name, bench->name, bench->fn, 1, argv); |
| 202 | printf("\n"); | 202 | printf("\n"); |
| 203 | } | 203 | } |
| 204 | } | 204 | } |
| @@ -211,7 +211,7 @@ static void run_all_collections(void) | |||
| 211 | run_collection(coll); | 211 | run_collection(coll); |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused) | 214 | int cmd_bench(int argc, const char **argv) |
| 215 | { | 215 | { |
| 216 | struct collection *coll; | 216 | struct collection *coll; |
| 217 | int ret = 0; | 217 | int ret = 0; |
| @@ -270,7 +270,7 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 270 | if (bench_format == BENCH_FORMAT_DEFAULT) | 270 | if (bench_format == BENCH_FORMAT_DEFAULT) |
| 271 | printf("# Running '%s/%s' benchmark:\n", coll->name, bench->name); | 271 | printf("# Running '%s/%s' benchmark:\n", coll->name, bench->name); |
| 272 | fflush(stdout); | 272 | fflush(stdout); |
| 273 | ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1, prefix); | 273 | ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1); |
| 274 | goto end; | 274 | goto end; |
| 275 | } | 275 | } |
| 276 | 276 | ||
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 30e2b2cb2421..94b55eee0d9b 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c | |||
| @@ -276,8 +276,7 @@ static int build_id_cache__update_file(const char *filename) | |||
| 276 | return err; | 276 | return err; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | int cmd_buildid_cache(int argc, const char **argv, | 279 | int cmd_buildid_cache(int argc, const char **argv) |
| 280 | const char *prefix __maybe_unused) | ||
| 281 | { | 280 | { |
| 282 | struct strlist *list; | 281 | struct strlist *list; |
| 283 | struct str_node *pos; | 282 | struct str_node *pos; |
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 5e914ee79eb3..26f4e608207f 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c | |||
| @@ -87,8 +87,7 @@ out: | |||
| 87 | return 0; | 87 | return 0; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | int cmd_buildid_list(int argc, const char **argv, | 90 | int cmd_buildid_list(int argc, const char **argv) |
| 91 | const char *prefix __maybe_unused) | ||
| 92 | { | 91 | { |
| 93 | bool show_kernel = false; | 92 | bool show_kernel = false; |
| 94 | bool with_hits = false; | 93 | bool with_hits = false; |
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 5cd6d7a047b9..70c2c773a2b8 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c | |||
| @@ -2755,12 +2755,12 @@ static int perf_c2c__record(int argc, const char **argv) | |||
| 2755 | pr_debug("\n"); | 2755 | pr_debug("\n"); |
| 2756 | } | 2756 | } |
| 2757 | 2757 | ||
| 2758 | ret = cmd_record(i, rec_argv, NULL); | 2758 | ret = cmd_record(i, rec_argv); |
| 2759 | free(rec_argv); | 2759 | free(rec_argv); |
| 2760 | return ret; | 2760 | return ret; |
| 2761 | } | 2761 | } |
| 2762 | 2762 | ||
| 2763 | int cmd_c2c(int argc, const char **argv, const char *prefix __maybe_unused) | 2763 | int cmd_c2c(int argc, const char **argv) |
| 2764 | { | 2764 | { |
| 2765 | argc = parse_options(argc, argv, c2c_options, c2c_usage, | 2765 | argc = parse_options(argc, argv, c2c_options, c2c_usage, |
| 2766 | PARSE_OPT_STOP_AT_NON_OPTION); | 2766 | PARSE_OPT_STOP_AT_NON_OPTION); |
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 8c0d93b7c2f0..55f04f85b049 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c | |||
| @@ -154,7 +154,7 @@ static int parse_config_arg(char *arg, char **var, char **value) | |||
| 154 | return 0; | 154 | return 0; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) | 157 | int cmd_config(int argc, const char **argv) |
| 158 | { | 158 | { |
| 159 | int i, ret = 0; | 159 | int i, ret = 0; |
| 160 | struct perf_config_set *set; | 160 | struct perf_config_set *set; |
diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index 7ad6e17ac6b3..0adb5f82335a 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include "data-convert.h" | 6 | #include "data-convert.h" |
| 7 | #include "data-convert-bt.h" | 7 | #include "data-convert-bt.h" |
| 8 | 8 | ||
| 9 | typedef int (*data_cmd_fn_t)(int argc, const char **argv, const char *prefix); | 9 | typedef int (*data_cmd_fn_t)(int argc, const char **argv); |
| 10 | 10 | ||
| 11 | struct data_cmd { | 11 | struct data_cmd { |
| 12 | const char *name; | 12 | const char *name; |
| @@ -50,8 +50,7 @@ static const char * const data_convert_usage[] = { | |||
| 50 | NULL | 50 | NULL |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | static int cmd_data_convert(int argc, const char **argv, | 53 | static int cmd_data_convert(int argc, const char **argv) |
| 54 | const char *prefix __maybe_unused) | ||
| 55 | { | 54 | { |
| 56 | const char *to_ctf = NULL; | 55 | const char *to_ctf = NULL; |
| 57 | struct perf_data_convert_opts opts = { | 56 | struct perf_data_convert_opts opts = { |
| @@ -98,7 +97,7 @@ static struct data_cmd data_cmds[] = { | |||
| 98 | { .name = NULL, }, | 97 | { .name = NULL, }, |
| 99 | }; | 98 | }; |
| 100 | 99 | ||
| 101 | int cmd_data(int argc, const char **argv, const char *prefix) | 100 | int cmd_data(int argc, const char **argv) |
| 102 | { | 101 | { |
| 103 | struct data_cmd *cmd; | 102 | struct data_cmd *cmd; |
| 104 | const char *cmdstr; | 103 | const char *cmdstr; |
| @@ -118,7 +117,7 @@ int cmd_data(int argc, const char **argv, const char *prefix) | |||
| 118 | if (strcmp(cmd->name, cmdstr)) | 117 | if (strcmp(cmd->name, cmdstr)) |
| 119 | continue; | 118 | continue; |
| 120 | 119 | ||
| 121 | return cmd->fn(argc, argv, prefix); | 120 | return cmd->fn(argc, argv); |
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | pr_err("Unknown command: %s\n", cmdstr); | 123 | pr_err("Unknown command: %s\n", cmdstr); |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 5e4803158672..cd2605d86984 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
| @@ -1321,7 +1321,7 @@ static int diff__config(const char *var, const char *value, | |||
| 1321 | return 0; | 1321 | return 0; |
| 1322 | } | 1322 | } |
| 1323 | 1323 | ||
| 1324 | int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) | 1324 | int cmd_diff(int argc, const char **argv) |
| 1325 | { | 1325 | { |
| 1326 | int ret = hists__init(); | 1326 | int ret = hists__init(); |
| 1327 | 1327 | ||
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index e09c4287fe87..6d210e40d611 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c | |||
| @@ -46,7 +46,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details | |||
| 46 | return 0; | 46 | return 0; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | int cmd_evlist(int argc, const char **argv, const char *prefix __maybe_unused) | 49 | int cmd_evlist(int argc, const char **argv) |
| 50 | { | 50 | { |
| 51 | struct perf_attr_details details = { .verbose = false, }; | 51 | struct perf_attr_details details = { .verbose = false, }; |
| 52 | const struct option options[] = { | 52 | const struct option options[] = { |
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 6087295f8827..f80fb60b00b0 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c | |||
| @@ -304,7 +304,7 @@ static int perf_ftrace_config(const char *var, const char *value, void *cb) | |||
| 304 | return -1; | 304 | return -1; |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused) | 307 | int cmd_ftrace(int argc, const char **argv) |
| 308 | { | 308 | { |
| 309 | int ret; | 309 | int ret; |
| 310 | struct perf_ftrace ftrace = { | 310 | struct perf_ftrace ftrace = { |
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index aed0d844e8c2..7ae238929e95 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c | |||
| @@ -418,7 +418,7 @@ static int show_html_page(const char *perf_cmd) | |||
| 418 | return 0; | 418 | return 0; |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused) | 421 | int cmd_help(int argc, const char **argv) |
| 422 | { | 422 | { |
| 423 | bool show_all = false; | 423 | bool show_all = false; |
| 424 | enum help_format help_format = HELP_FORMAT_MAN; | 424 | enum help_format help_format = HELP_FORMAT_MAN; |
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 8d1d13b9bab6..42dff0b1375a 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
| @@ -738,7 +738,7 @@ static int __cmd_inject(struct perf_inject *inject) | |||
| 738 | return ret; | 738 | return ret; |
| 739 | } | 739 | } |
| 740 | 740 | ||
| 741 | int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) | 741 | int cmd_inject(int argc, const char **argv) |
| 742 | { | 742 | { |
| 743 | struct perf_inject inject = { | 743 | struct perf_inject inject = { |
| 744 | .tool = { | 744 | .tool = { |
diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c index 224bfc454b4a..8ff38c4eb2c0 100644 --- a/tools/perf/builtin-kallsyms.c +++ b/tools/perf/builtin-kallsyms.c | |||
| @@ -43,7 +43,7 @@ static int __cmd_kallsyms(int argc, const char **argv) | |||
| 43 | return 0; | 43 | return 0; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | int cmd_kallsyms(int argc, const char **argv, const char *prefix __maybe_unused) | 46 | int cmd_kallsyms(int argc, const char **argv) |
| 47 | { | 47 | { |
| 48 | const struct option options[] = { | 48 | const struct option options[] = { |
| 49 | OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), | 49 | OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index d509e74bc6e8..515587825af4 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
| @@ -1866,7 +1866,7 @@ static int __cmd_record(int argc, const char **argv) | |||
| 1866 | for (j = 1; j < (unsigned int)argc; j++, i++) | 1866 | for (j = 1; j < (unsigned int)argc; j++, i++) |
| 1867 | rec_argv[i] = argv[j]; | 1867 | rec_argv[i] = argv[j]; |
| 1868 | 1868 | ||
| 1869 | return cmd_record(i, rec_argv, NULL); | 1869 | return cmd_record(i, rec_argv); |
| 1870 | } | 1870 | } |
| 1871 | 1871 | ||
| 1872 | static int kmem_config(const char *var, const char *value, void *cb __maybe_unused) | 1872 | static int kmem_config(const char *var, const char *value, void *cb __maybe_unused) |
| @@ -1885,7 +1885,7 @@ static int kmem_config(const char *var, const char *value, void *cb __maybe_unus | |||
| 1885 | return 0; | 1885 | return 0; |
| 1886 | } | 1886 | } |
| 1887 | 1887 | ||
| 1888 | int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) | 1888 | int cmd_kmem(int argc, const char **argv) |
| 1889 | { | 1889 | { |
| 1890 | const char * const default_slab_sort = "frag,hit,bytes"; | 1890 | const char * const default_slab_sort = "frag,hit,bytes"; |
| 1891 | const char * const default_page_sort = "bytes,hit"; | 1891 | const char * const default_page_sort = "bytes,hit"; |
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 18e6c38864bc..38b409173693 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
| @@ -1209,7 +1209,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) | |||
| 1209 | set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED); | 1209 | set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED); |
| 1210 | 1210 | ||
| 1211 | record_usage = kvm_stat_record_usage; | 1211 | record_usage = kvm_stat_record_usage; |
| 1212 | return cmd_record(i, rec_argv, NULL); | 1212 | return cmd_record(i, rec_argv); |
| 1213 | } | 1213 | } |
| 1214 | 1214 | ||
| 1215 | static int | 1215 | static int |
| @@ -1477,7 +1477,7 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv) | |||
| 1477 | #endif | 1477 | #endif |
| 1478 | 1478 | ||
| 1479 | perf_stat: | 1479 | perf_stat: |
| 1480 | return cmd_stat(argc, argv, NULL); | 1480 | return cmd_stat(argc, argv); |
| 1481 | } | 1481 | } |
| 1482 | #endif /* HAVE_KVM_STAT_SUPPORT */ | 1482 | #endif /* HAVE_KVM_STAT_SUPPORT */ |
| 1483 | 1483 | ||
| @@ -1496,7 +1496,7 @@ static int __cmd_record(const char *file_name, int argc, const char **argv) | |||
| 1496 | 1496 | ||
| 1497 | BUG_ON(i != rec_argc); | 1497 | BUG_ON(i != rec_argc); |
| 1498 | 1498 | ||
| 1499 | return cmd_record(i, rec_argv, NULL); | 1499 | return cmd_record(i, rec_argv); |
| 1500 | } | 1500 | } |
| 1501 | 1501 | ||
| 1502 | static int __cmd_report(const char *file_name, int argc, const char **argv) | 1502 | static int __cmd_report(const char *file_name, int argc, const char **argv) |
| @@ -1514,7 +1514,7 @@ static int __cmd_report(const char *file_name, int argc, const char **argv) | |||
| 1514 | 1514 | ||
| 1515 | BUG_ON(i != rec_argc); | 1515 | BUG_ON(i != rec_argc); |
| 1516 | 1516 | ||
| 1517 | return cmd_report(i, rec_argv, NULL); | 1517 | return cmd_report(i, rec_argv); |
| 1518 | } | 1518 | } |
| 1519 | 1519 | ||
| 1520 | static int | 1520 | static int |
| @@ -1533,10 +1533,10 @@ __cmd_buildid_list(const char *file_name, int argc, const char **argv) | |||
| 1533 | 1533 | ||
| 1534 | BUG_ON(i != rec_argc); | 1534 | BUG_ON(i != rec_argc); |
| 1535 | 1535 | ||
| 1536 | return cmd_buildid_list(i, rec_argv, NULL); | 1536 | return cmd_buildid_list(i, rec_argv); |
| 1537 | } | 1537 | } |
| 1538 | 1538 | ||
| 1539 | int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused) | 1539 | int cmd_kvm(int argc, const char **argv) |
| 1540 | { | 1540 | { |
| 1541 | const char *file_name = NULL; | 1541 | const char *file_name = NULL; |
| 1542 | const struct option kvm_options[] = { | 1542 | const struct option kvm_options[] = { |
| @@ -1591,9 +1591,9 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 1591 | else if (!strncmp(argv[0], "rep", 3)) | 1591 | else if (!strncmp(argv[0], "rep", 3)) |
| 1592 | return __cmd_report(file_name, argc, argv); | 1592 | return __cmd_report(file_name, argc, argv); |
| 1593 | else if (!strncmp(argv[0], "diff", 4)) | 1593 | else if (!strncmp(argv[0], "diff", 4)) |
| 1594 | return cmd_diff(argc, argv, NULL); | 1594 | return cmd_diff(argc, argv); |
| 1595 | else if (!strncmp(argv[0], "top", 3)) | 1595 | else if (!strncmp(argv[0], "top", 3)) |
| 1596 | return cmd_top(argc, argv, NULL); | 1596 | return cmd_top(argc, argv); |
| 1597 | else if (!strncmp(argv[0], "buildid-list", 12)) | 1597 | else if (!strncmp(argv[0], "buildid-list", 12)) |
| 1598 | return __cmd_buildid_list(file_name, argc, argv); | 1598 | return __cmd_buildid_list(file_name, argc, argv); |
| 1599 | #ifdef HAVE_KVM_STAT_SUPPORT | 1599 | #ifdef HAVE_KVM_STAT_SUPPORT |
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index be9195e95c78..4bf2cb4d25aa 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | static bool desc_flag = true; | 20 | static bool desc_flag = true; |
| 21 | static bool details_flag; | 21 | static bool details_flag; |
| 22 | 22 | ||
| 23 | int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) | 23 | int cmd_list(int argc, const char **argv) |
| 24 | { | 24 | { |
| 25 | int i; | 25 | int i; |
| 26 | bool raw_dump = false; | 26 | bool raw_dump = false; |
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index e992e7206993..b686fb6759da 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
| @@ -941,12 +941,12 @@ static int __cmd_record(int argc, const char **argv) | |||
| 941 | 941 | ||
| 942 | BUG_ON(i != rec_argc); | 942 | BUG_ON(i != rec_argc); |
| 943 | 943 | ||
| 944 | ret = cmd_record(i, rec_argv, NULL); | 944 | ret = cmd_record(i, rec_argv); |
| 945 | free(rec_argv); | 945 | free(rec_argv); |
| 946 | return ret; | 946 | return ret; |
| 947 | } | 947 | } |
| 948 | 948 | ||
| 949 | int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused) | 949 | int cmd_lock(int argc, const char **argv) |
| 950 | { | 950 | { |
| 951 | const struct option lock_options[] = { | 951 | const struct option lock_options[] = { |
| 952 | OPT_STRING('i', "input", &input_name, "file", "input file name"), | 952 | OPT_STRING('i', "input", &input_name, "file", "input file name"), |
| @@ -1009,7 +1009,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 1009 | rc = __cmd_report(false); | 1009 | rc = __cmd_report(false); |
| 1010 | } else if (!strcmp(argv[0], "script")) { | 1010 | } else if (!strcmp(argv[0], "script")) { |
| 1011 | /* Aliased to 'perf script' */ | 1011 | /* Aliased to 'perf script' */ |
| 1012 | return cmd_script(argc, argv, prefix); | 1012 | return cmd_script(argc, argv); |
| 1013 | } else if (!strcmp(argv[0], "info")) { | 1013 | } else if (!strcmp(argv[0], "info")) { |
| 1014 | if (argc) { | 1014 | if (argc) { |
| 1015 | argc = parse_options(argc, argv, | 1015 | argc = parse_options(argc, argv, |
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 030a6cfdda59..643f4faac0d0 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c | |||
| @@ -129,7 +129,7 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) | |||
| 129 | pr_debug("\n"); | 129 | pr_debug("\n"); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | ret = cmd_record(i, rec_argv, NULL); | 132 | ret = cmd_record(i, rec_argv); |
| 133 | free(rec_argv); | 133 | free(rec_argv); |
| 134 | return ret; | 134 | return ret; |
| 135 | } | 135 | } |
| @@ -256,7 +256,7 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem) | |||
| 256 | for (j = 1; j < argc; j++, i++) | 256 | for (j = 1; j < argc; j++, i++) |
| 257 | rep_argv[i] = argv[j]; | 257 | rep_argv[i] = argv[j]; |
| 258 | 258 | ||
| 259 | ret = cmd_report(i, rep_argv, NULL); | 259 | ret = cmd_report(i, rep_argv); |
| 260 | free(rep_argv); | 260 | free(rep_argv); |
| 261 | return ret; | 261 | return ret; |
| 262 | } | 262 | } |
| @@ -330,7 +330,7 @@ error: | |||
| 330 | return ret; | 330 | return ret; |
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused) | 333 | int cmd_mem(int argc, const char **argv) |
| 334 | { | 334 | { |
| 335 | struct stat st; | 335 | struct stat st; |
| 336 | struct perf_mem mem = { | 336 | struct perf_mem mem = { |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 51cdc230f6ca..d7360c2bda13 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
| @@ -468,7 +468,7 @@ out: | |||
| 468 | 468 | ||
| 469 | 469 | ||
| 470 | static int | 470 | static int |
| 471 | __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | 471 | __cmd_probe(int argc, const char **argv) |
| 472 | { | 472 | { |
| 473 | const char * const probe_usage[] = { | 473 | const char * const probe_usage[] = { |
| 474 | "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", | 474 | "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", |
| @@ -687,13 +687,13 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 687 | return 0; | 687 | return 0; |
| 688 | } | 688 | } |
| 689 | 689 | ||
| 690 | int cmd_probe(int argc, const char **argv, const char *prefix) | 690 | int cmd_probe(int argc, const char **argv) |
| 691 | { | 691 | { |
| 692 | int ret; | 692 | int ret; |
| 693 | 693 | ||
| 694 | ret = init_params(); | 694 | ret = init_params(); |
| 695 | if (!ret) { | 695 | if (!ret) { |
| 696 | ret = __cmd_probe(argc, argv, prefix); | 696 | ret = __cmd_probe(argc, argv); |
| 697 | cleanup_params(); | 697 | cleanup_params(); |
| 698 | } | 698 | } |
| 699 | 699 | ||
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 04faef79a548..3191ab063852 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -1667,7 +1667,7 @@ static struct option __record_options[] = { | |||
| 1667 | 1667 | ||
| 1668 | struct option *record_options = __record_options; | 1668 | struct option *record_options = __record_options; |
| 1669 | 1669 | ||
| 1670 | int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | 1670 | int cmd_record(int argc, const char **argv) |
| 1671 | { | 1671 | { |
| 1672 | int err; | 1672 | int err; |
| 1673 | struct record *rec = &record; | 1673 | struct record *rec = &record; |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 5ab8117c3bfd..c18158b83eb1 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -681,7 +681,7 @@ const char report_callchain_help[] = "Display call graph (stack chain/backtrace) | |||
| 681 | CALLCHAIN_REPORT_HELP | 681 | CALLCHAIN_REPORT_HELP |
| 682 | "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT; | 682 | "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT; |
| 683 | 683 | ||
| 684 | int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | 684 | int cmd_report(int argc, const char **argv) |
| 685 | { | 685 | { |
| 686 | struct perf_session *session; | 686 | struct perf_session *session; |
| 687 | struct itrace_synth_opts itrace_synth_opts = { .set = 0, }; | 687 | struct itrace_synth_opts itrace_synth_opts = { .set = 0, }; |
| @@ -845,6 +845,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 845 | stdio__config_color, "always"), | 845 | stdio__config_color, "always"), |
| 846 | OPT_STRING(0, "time", &report.time_str, "str", | 846 | OPT_STRING(0, "time", &report.time_str, "str", |
| 847 | "Time span of interest (start,stop)"), | 847 | "Time span of interest (start,stop)"), |
| 848 | OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name, | ||
| 849 | "Show inline function"), | ||
| 848 | OPT_END() | 850 | OPT_END() |
| 849 | }; | 851 | }; |
| 850 | struct perf_data_file file = { | 852 | struct perf_data_file file = { |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index b92c4d97192c..79833e226789 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
| @@ -3272,10 +3272,10 @@ static int __cmd_record(int argc, const char **argv) | |||
| 3272 | 3272 | ||
| 3273 | BUG_ON(i != rec_argc); | 3273 | BUG_ON(i != rec_argc); |
| 3274 | 3274 | ||
| 3275 | return cmd_record(i, rec_argv, NULL); | 3275 | return cmd_record(i, rec_argv); |
| 3276 | } | 3276 | } |
| 3277 | 3277 | ||
| 3278 | int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) | 3278 | int cmd_sched(int argc, const char **argv) |
| 3279 | { | 3279 | { |
| 3280 | const char default_sort_order[] = "avg, max, switch, runtime"; | 3280 | const char default_sort_order[] = "avg, max, switch, runtime"; |
| 3281 | struct perf_sched sched = { | 3281 | struct perf_sched sched = { |
| @@ -3412,7 +3412,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 3412 | * Aliased to 'perf script' for now: | 3412 | * Aliased to 'perf script' for now: |
| 3413 | */ | 3413 | */ |
| 3414 | if (!strcmp(argv[0], "script")) | 3414 | if (!strcmp(argv[0], "script")) |
| 3415 | return cmd_script(argc, argv, prefix); | 3415 | return cmd_script(argc, argv); |
| 3416 | 3416 | ||
| 3417 | if (!strncmp(argv[0], "rec", 3)) { | 3417 | if (!strncmp(argv[0], "rec", 3)) { |
| 3418 | return __cmd_record(argc, argv); | 3418 | return __cmd_record(argc, argv); |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index c98e16689b57..46acc8ece41f 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
| @@ -2359,7 +2359,7 @@ int process_cpu_map_event(struct perf_tool *tool __maybe_unused, | |||
| 2359 | return set_maps(script); | 2359 | return set_maps(script); |
| 2360 | } | 2360 | } |
| 2361 | 2361 | ||
| 2362 | int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | 2362 | int cmd_script(int argc, const char **argv) |
| 2363 | { | 2363 | { |
| 2364 | bool show_full_info = false; | 2364 | bool show_full_info = false; |
| 2365 | bool header = false; | 2365 | bool header = false; |
| @@ -2504,7 +2504,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 2504 | if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { | 2504 | if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { |
| 2505 | rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); | 2505 | rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); |
| 2506 | if (!rec_script_path) | 2506 | if (!rec_script_path) |
| 2507 | return cmd_record(argc, argv, NULL); | 2507 | return cmd_record(argc, argv); |
| 2508 | } | 2508 | } |
| 2509 | 2509 | ||
| 2510 | if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) { | 2510 | if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) { |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 01b589e3c3a6..2158ea14da57 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -2478,7 +2478,7 @@ static void setup_system_wide(int forks) | |||
| 2478 | } | 2478 | } |
| 2479 | } | 2479 | } |
| 2480 | 2480 | ||
| 2481 | int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) | 2481 | int cmd_stat(int argc, const char **argv) |
| 2482 | { | 2482 | { |
| 2483 | const char * const stat_usage[] = { | 2483 | const char * const stat_usage[] = { |
| 2484 | "perf stat [<options>] [<command>]", | 2484 | "perf stat [<options>] [<command>]", |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index fbd7c6c695b8..fafdb44b8bcb 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
| @@ -1773,7 +1773,7 @@ static int timechart__io_record(int argc, const char **argv) | |||
| 1773 | for (i = 0; i < (unsigned int)argc; i++) | 1773 | for (i = 0; i < (unsigned int)argc; i++) |
| 1774 | *p++ = argv[i]; | 1774 | *p++ = argv[i]; |
| 1775 | 1775 | ||
| 1776 | return cmd_record(rec_argc, rec_argv, NULL); | 1776 | return cmd_record(rec_argc, rec_argv); |
| 1777 | } | 1777 | } |
| 1778 | 1778 | ||
| 1779 | 1779 | ||
| @@ -1864,7 +1864,7 @@ static int timechart__record(struct timechart *tchart, int argc, const char **ar | |||
| 1864 | for (j = 0; j < (unsigned int)argc; j++) | 1864 | for (j = 0; j < (unsigned int)argc; j++) |
| 1865 | *p++ = argv[j]; | 1865 | *p++ = argv[j]; |
| 1866 | 1866 | ||
| 1867 | return cmd_record(rec_argc, rec_argv, NULL); | 1867 | return cmd_record(rec_argc, rec_argv); |
| 1868 | } | 1868 | } |
| 1869 | 1869 | ||
| 1870 | static int | 1870 | static int |
| @@ -1917,8 +1917,7 @@ parse_time(const struct option *opt, const char *arg, int __maybe_unused unset) | |||
| 1917 | return 0; | 1917 | return 0; |
| 1918 | } | 1918 | } |
| 1919 | 1919 | ||
| 1920 | int cmd_timechart(int argc, const char **argv, | 1920 | int cmd_timechart(int argc, const char **argv) |
| 1921 | const char *prefix __maybe_unused) | ||
| 1922 | { | 1921 | { |
| 1923 | struct timechart tchart = { | 1922 | struct timechart tchart = { |
| 1924 | .tool = { | 1923 | .tool = { |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index ab9077915763..a0c97c70ec81 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -1075,7 +1075,7 @@ parse_percent_limit(const struct option *opt, const char *arg, | |||
| 1075 | const char top_callchain_help[] = CALLCHAIN_RECORD_HELP CALLCHAIN_REPORT_HELP | 1075 | const char top_callchain_help[] = CALLCHAIN_RECORD_HELP CALLCHAIN_REPORT_HELP |
| 1076 | "\n\t\t\t\tDefault: fp,graph,0.5,caller,function"; | 1076 | "\n\t\t\t\tDefault: fp,graph,0.5,caller,function"; |
| 1077 | 1077 | ||
| 1078 | int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | 1078 | int cmd_top(int argc, const char **argv) |
| 1079 | { | 1079 | { |
| 1080 | char errbuf[BUFSIZ]; | 1080 | char errbuf[BUFSIZ]; |
| 1081 | struct perf_top top = { | 1081 | struct perf_top top = { |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 912fedc5b42d..c88f9f215e6f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -1653,15 +1653,17 @@ static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel, | |||
| 1653 | 1653 | ||
| 1654 | ttrace = thread__priv(thread); | 1654 | ttrace = thread__priv(thread); |
| 1655 | if (!ttrace) | 1655 | if (!ttrace) |
| 1656 | goto out; | 1656 | goto out_put; |
| 1657 | 1657 | ||
| 1658 | filename_len = strlen(filename); | 1658 | filename_len = strlen(filename); |
| 1659 | if (filename_len == 0) | ||
| 1660 | goto out_put; | ||
| 1659 | 1661 | ||
| 1660 | if (ttrace->filename.namelen < filename_len) { | 1662 | if (ttrace->filename.namelen < filename_len) { |
| 1661 | char *f = realloc(ttrace->filename.name, filename_len + 1); | 1663 | char *f = realloc(ttrace->filename.name, filename_len + 1); |
| 1662 | 1664 | ||
| 1663 | if (f == NULL) | 1665 | if (f == NULL) |
| 1664 | goto out; | 1666 | goto out_put; |
| 1665 | 1667 | ||
| 1666 | ttrace->filename.namelen = filename_len; | 1668 | ttrace->filename.namelen = filename_len; |
| 1667 | ttrace->filename.name = f; | 1669 | ttrace->filename.name = f; |
| @@ -1671,12 +1673,12 @@ static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel, | |||
| 1671 | ttrace->filename.pending_open = true; | 1673 | ttrace->filename.pending_open = true; |
| 1672 | 1674 | ||
| 1673 | if (!ttrace->filename.ptr) | 1675 | if (!ttrace->filename.ptr) |
| 1674 | goto out; | 1676 | goto out_put; |
| 1675 | 1677 | ||
| 1676 | entry_str_len = strlen(ttrace->entry_str); | 1678 | entry_str_len = strlen(ttrace->entry_str); |
| 1677 | remaining_space = trace__entry_str_size - entry_str_len - 1; /* \0 */ | 1679 | remaining_space = trace__entry_str_size - entry_str_len - 1; /* \0 */ |
| 1678 | if (remaining_space <= 0) | 1680 | if (remaining_space <= 0) |
| 1679 | goto out; | 1681 | goto out_put; |
| 1680 | 1682 | ||
| 1681 | if (filename_len > (size_t)remaining_space) { | 1683 | if (filename_len > (size_t)remaining_space) { |
| 1682 | filename += filename_len - remaining_space; | 1684 | filename += filename_len - remaining_space; |
| @@ -1690,6 +1692,8 @@ static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel, | |||
| 1690 | 1692 | ||
| 1691 | ttrace->filename.ptr = 0; | 1693 | ttrace->filename.ptr = 0; |
| 1692 | ttrace->filename.entry_str_pos = 0; | 1694 | ttrace->filename.entry_str_pos = 0; |
| 1695 | out_put: | ||
| 1696 | thread__put(thread); | ||
| 1693 | out: | 1697 | out: |
| 1694 | return 0; | 1698 | return 0; |
| 1695 | } | 1699 | } |
| @@ -1710,6 +1714,7 @@ static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evs | |||
| 1710 | 1714 | ||
| 1711 | ttrace->runtime_ms += runtime_ms; | 1715 | ttrace->runtime_ms += runtime_ms; |
| 1712 | trace->runtime_ms += runtime_ms; | 1716 | trace->runtime_ms += runtime_ms; |
| 1717 | out_put: | ||
| 1713 | thread__put(thread); | 1718 | thread__put(thread); |
| 1714 | return 0; | 1719 | return 0; |
| 1715 | 1720 | ||
| @@ -1720,8 +1725,7 @@ out_dump: | |||
| 1720 | (pid_t)perf_evsel__intval(evsel, sample, "pid"), | 1725 | (pid_t)perf_evsel__intval(evsel, sample, "pid"), |
| 1721 | runtime, | 1726 | runtime, |
| 1722 | perf_evsel__intval(evsel, sample, "vruntime")); | 1727 | perf_evsel__intval(evsel, sample, "vruntime")); |
| 1723 | thread__put(thread); | 1728 | goto out_put; |
| 1724 | return 0; | ||
| 1725 | } | 1729 | } |
| 1726 | 1730 | ||
| 1727 | static void bpf_output__printer(enum binary_printer_ops op, | 1731 | static void bpf_output__printer(enum binary_printer_ops op, |
| @@ -1920,7 +1924,7 @@ static int trace__process_sample(struct perf_tool *tool, | |||
| 1920 | 1924 | ||
| 1921 | thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); | 1925 | thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); |
| 1922 | if (thread && thread__is_filtered(thread)) | 1926 | if (thread && thread__is_filtered(thread)) |
| 1923 | return 0; | 1927 | goto out; |
| 1924 | 1928 | ||
| 1925 | trace__set_base_time(trace, evsel, sample); | 1929 | trace__set_base_time(trace, evsel, sample); |
| 1926 | 1930 | ||
| @@ -1928,7 +1932,8 @@ static int trace__process_sample(struct perf_tool *tool, | |||
| 1928 | ++trace->nr_events; | 1932 | ++trace->nr_events; |
| 1929 | handler(trace, evsel, event, sample); | 1933 | handler(trace, evsel, event, sample); |
| 1930 | } | 1934 | } |
| 1931 | 1935 | out: | |
| 1936 | thread__put(thread); | ||
| 1932 | return err; | 1937 | return err; |
| 1933 | } | 1938 | } |
| 1934 | 1939 | ||
| @@ -1988,7 +1993,7 @@ static int trace__record(struct trace *trace, int argc, const char **argv) | |||
| 1988 | for (i = 0; i < (unsigned int)argc; i++) | 1993 | for (i = 0; i < (unsigned int)argc; i++) |
| 1989 | rec_argv[j++] = argv[i]; | 1994 | rec_argv[j++] = argv[i]; |
| 1990 | 1995 | ||
| 1991 | return cmd_record(j, rec_argv, NULL); | 1996 | return cmd_record(j, rec_argv); |
| 1992 | } | 1997 | } |
| 1993 | 1998 | ||
| 1994 | static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); | 1999 | static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); |
| @@ -2786,7 +2791,7 @@ out: | |||
| 2786 | return err; | 2791 | return err; |
| 2787 | } | 2792 | } |
| 2788 | 2793 | ||
| 2789 | int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) | 2794 | int cmd_trace(int argc, const char **argv) |
| 2790 | { | 2795 | { |
| 2791 | const char *trace_usage[] = { | 2796 | const char *trace_usage[] = { |
| 2792 | "perf trace [<options>] [<command>]", | 2797 | "perf trace [<options>] [<command>]", |
diff --git a/tools/perf/builtin-version.c b/tools/perf/builtin-version.c index 9b10cda6b6dc..b9a095b1db99 100644 --- a/tools/perf/builtin-version.c +++ b/tools/perf/builtin-version.c | |||
| @@ -2,8 +2,7 @@ | |||
| 2 | #include "builtin.h" | 2 | #include "builtin.h" |
| 3 | #include "perf.h" | 3 | #include "perf.h" |
| 4 | 4 | ||
| 5 | int cmd_version(int argc __maybe_unused, const char **argv __maybe_unused, | 5 | int cmd_version(int argc __maybe_unused, const char **argv __maybe_unused) |
| 6 | const char *prefix __maybe_unused) | ||
| 7 | { | 6 | { |
| 8 | printf("perf version %s\n", perf_version_string); | 7 | printf("perf version %s\n", perf_version_string); |
| 9 | return 0; | 8 | return 0; |
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h index 036e1e35b1a8..26669bf9129c 100644 --- a/tools/perf/builtin.h +++ b/tools/perf/builtin.h | |||
| @@ -13,35 +13,35 @@ void prune_packed_objects(int); | |||
| 13 | int read_line_with_nul(char *buf, int size, FILE *file); | 13 | int read_line_with_nul(char *buf, int size, FILE *file); |
| 14 | int check_pager_config(const char *cmd); | 14 | int check_pager_config(const char *cmd); |
| 15 | 15 | ||
| 16 | int cmd_annotate(int argc, const char **argv, const char *prefix); | 16 | int cmd_annotate(int argc, const char **argv); |
| 17 | int cmd_bench(int argc, const char **argv, const char *prefix); | 17 | int cmd_bench(int argc, const char **argv); |
| 18 | int cmd_buildid_cache(int argc, const char **argv, const char *prefix); | 18 | int cmd_buildid_cache(int argc, const char **argv); |
| 19 | int cmd_buildid_list(int argc, const char **argv, const char *prefix); | 19 | int cmd_buildid_list(int argc, const char **argv); |
| 20 | int cmd_config(int argc, const char **argv, const char *prefix); | 20 | int cmd_config(int argc, const char **argv); |
| 21 | int cmd_c2c(int argc, const char **argv, const char *prefix); | 21 | int cmd_c2c(int argc, const char **argv); |
| 22 | int cmd_diff(int argc, const char **argv, const char *prefix); | 22 | int cmd_diff(int argc, const char **argv); |
| 23 | int cmd_evlist(int argc, const char **argv, const char *prefix); | 23 | int cmd_evlist(int argc, const char **argv); |
| 24 | int cmd_help(int argc, const char **argv, const char *prefix); | 24 | int cmd_help(int argc, const char **argv); |
| 25 | int cmd_sched(int argc, const char **argv, const char *prefix); | 25 | int cmd_sched(int argc, const char **argv); |
| 26 | int cmd_kallsyms(int argc, const char **argv, const char *prefix); | 26 | int cmd_kallsyms(int argc, const char **argv); |
| 27 | int cmd_list(int argc, const char **argv, const char *prefix); | 27 | int cmd_list(int argc, const char **argv); |
| 28 | int cmd_record(int argc, const char **argv, const char *prefix); | 28 | int cmd_record(int argc, const char **argv); |
| 29 | int cmd_report(int argc, const char **argv, const char *prefix); | 29 | int cmd_report(int argc, const char **argv); |
| 30 | int cmd_stat(int argc, const char **argv, const char *prefix); | 30 | int cmd_stat(int argc, const char **argv); |
| 31 | int cmd_timechart(int argc, const char **argv, const char *prefix); | 31 | int cmd_timechart(int argc, const char **argv); |
| 32 | int cmd_top(int argc, const char **argv, const char *prefix); | 32 | int cmd_top(int argc, const char **argv); |
| 33 | int cmd_script(int argc, const char **argv, const char *prefix); | 33 | int cmd_script(int argc, const char **argv); |
| 34 | int cmd_version(int argc, const char **argv, const char *prefix); | 34 | int cmd_version(int argc, const char **argv); |
| 35 | int cmd_probe(int argc, const char **argv, const char *prefix); | 35 | int cmd_probe(int argc, const char **argv); |
| 36 | int cmd_kmem(int argc, const char **argv, const char *prefix); | 36 | int cmd_kmem(int argc, const char **argv); |
| 37 | int cmd_lock(int argc, const char **argv, const char *prefix); | 37 | int cmd_lock(int argc, const char **argv); |
| 38 | int cmd_kvm(int argc, const char **argv, const char *prefix); | 38 | int cmd_kvm(int argc, const char **argv); |
| 39 | int cmd_test(int argc, const char **argv, const char *prefix); | 39 | int cmd_test(int argc, const char **argv); |
| 40 | int cmd_trace(int argc, const char **argv, const char *prefix); | 40 | int cmd_trace(int argc, const char **argv); |
| 41 | int cmd_inject(int argc, const char **argv, const char *prefix); | 41 | int cmd_inject(int argc, const char **argv); |
| 42 | int cmd_mem(int argc, const char **argv, const char *prefix); | 42 | int cmd_mem(int argc, const char **argv); |
| 43 | int cmd_data(int argc, const char **argv, const char *prefix); | 43 | int cmd_data(int argc, const char **argv); |
| 44 | int cmd_ftrace(int argc, const char **argv, const char *prefix); | 44 | int cmd_ftrace(int argc, const char **argv); |
| 45 | 45 | ||
| 46 | int find_scripts(char **scripts_array, char **scripts_path_array); | 46 | int find_scripts(char **scripts_array, char **scripts_path_array); |
| 47 | #endif | 47 | #endif |
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 6d5479e03e0d..4b283d18e158 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c | |||
| @@ -34,7 +34,7 @@ const char *input_name; | |||
| 34 | 34 | ||
| 35 | struct cmd_struct { | 35 | struct cmd_struct { |
| 36 | const char *cmd; | 36 | const char *cmd; |
| 37 | int (*fn)(int, const char **, const char *); | 37 | int (*fn)(int, const char **); |
| 38 | int option; | 38 | int option; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| @@ -339,13 +339,8 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) | |||
| 339 | { | 339 | { |
| 340 | int status; | 340 | int status; |
| 341 | struct stat st; | 341 | struct stat st; |
| 342 | const char *prefix; | ||
| 343 | char sbuf[STRERR_BUFSIZE]; | 342 | char sbuf[STRERR_BUFSIZE]; |
| 344 | 343 | ||
| 345 | prefix = NULL; | ||
| 346 | if (p->option & RUN_SETUP) | ||
| 347 | prefix = NULL; /* setup_perf_directory(); */ | ||
| 348 | |||
| 349 | if (use_browser == -1) | 344 | if (use_browser == -1) |
| 350 | use_browser = check_browser_config(p->cmd); | 345 | use_browser = check_browser_config(p->cmd); |
| 351 | 346 | ||
| @@ -356,7 +351,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) | |||
| 356 | commit_pager_choice(); | 351 | commit_pager_choice(); |
| 357 | 352 | ||
| 358 | perf_env__set_cmdline(&perf_env, argc, argv); | 353 | perf_env__set_cmdline(&perf_env, argc, argv); |
| 359 | status = p->fn(argc, argv, prefix); | 354 | status = p->fn(argc, argv); |
| 360 | perf_config__exit(); | 355 | perf_config__exit(); |
| 361 | exit_browser(status); | 356 | exit_browser(status); |
| 362 | perf_env__exit(&perf_env); | 357 | perf_env__exit(&perf_env); |
| @@ -566,7 +561,7 @@ int main(int argc, const char **argv) | |||
| 566 | #ifdef HAVE_LIBAUDIT_SUPPORT | 561 | #ifdef HAVE_LIBAUDIT_SUPPORT |
| 567 | setup_path(); | 562 | setup_path(); |
| 568 | argv[0] = "trace"; | 563 | argv[0] = "trace"; |
| 569 | return cmd_trace(argc, argv, NULL); | 564 | return cmd_trace(argc, argv); |
| 570 | #else | 565 | #else |
| 571 | fprintf(stderr, | 566 | fprintf(stderr, |
| 572 | "trace command not available: missing audit-libs devel package at build time.\n"); | 567 | "trace command not available: missing audit-libs devel package at build time.\n"); |
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 86822969e8a8..e6d7876c94c2 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c | |||
| @@ -464,7 +464,7 @@ static int perf_test__list(int argc, const char **argv) | |||
| 464 | return 0; | 464 | return 0; |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused) | 467 | int cmd_test(int argc, const char **argv) |
| 468 | { | 468 | { |
| 469 | const char *test_usage[] = { | 469 | const char *test_usage[] = { |
| 470 | "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]", | 470 | "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]", |
diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index f59d210e1baf..26e5b7a0b839 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c | |||
| @@ -43,7 +43,7 @@ static char *get_self_path(void) | |||
| 43 | { | 43 | { |
| 44 | char *buf = calloc(PATH_MAX, sizeof(char)); | 44 | char *buf = calloc(PATH_MAX, sizeof(char)); |
| 45 | 45 | ||
| 46 | if (buf && readlink("/proc/self/exe", buf, PATH_MAX) < 0) { | 46 | if (buf && readlink("/proc/self/exe", buf, PATH_MAX - 1) < 0) { |
| 47 | pr_debug("Failed to get correct path of perf\n"); | 47 | pr_debug("Failed to get correct path of perf\n"); |
| 48 | free(buf); | 48 | free(buf); |
| 49 | return NULL; | 49 | return NULL; |
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 2dc82bec10c0..da24072bb76e 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
| @@ -144,9 +144,60 @@ static void callchain_list__set_folding(struct callchain_list *cl, bool unfold) | |||
| 144 | cl->unfolded = unfold ? cl->has_children : false; | 144 | cl->unfolded = unfold ? cl->has_children : false; |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | static struct inline_node *inline_node__create(struct map *map, u64 ip) | ||
| 148 | { | ||
| 149 | struct dso *dso; | ||
| 150 | struct inline_node *node; | ||
| 151 | |||
| 152 | if (map == NULL) | ||
| 153 | return NULL; | ||
| 154 | |||
| 155 | dso = map->dso; | ||
| 156 | if (dso == NULL) | ||
| 157 | return NULL; | ||
| 158 | |||
| 159 | if (dso->kernel != DSO_TYPE_USER) | ||
| 160 | return NULL; | ||
| 161 | |||
| 162 | node = dso__parse_addr_inlines(dso, | ||
| 163 | map__rip_2objdump(map, ip)); | ||
| 164 | |||
| 165 | return node; | ||
| 166 | } | ||
| 167 | |||
| 168 | static int inline__count_rows(struct inline_node *node) | ||
| 169 | { | ||
| 170 | struct inline_list *ilist; | ||
| 171 | int i = 0; | ||
| 172 | |||
| 173 | if (node == NULL) | ||
| 174 | return 0; | ||
| 175 | |||
| 176 | list_for_each_entry(ilist, &node->val, list) { | ||
| 177 | if ((ilist->filename != NULL) || (ilist->funcname != NULL)) | ||
| 178 | i++; | ||
| 179 | } | ||
| 180 | |||
| 181 | return i; | ||
| 182 | } | ||
| 183 | |||
| 184 | static int callchain_list__inline_rows(struct callchain_list *chain) | ||
| 185 | { | ||
| 186 | struct inline_node *node; | ||
| 187 | int rows; | ||
| 188 | |||
| 189 | node = inline_node__create(chain->ms.map, chain->ip); | ||
| 190 | if (node == NULL) | ||
| 191 | return 0; | ||
| 192 | |||
| 193 | rows = inline__count_rows(node); | ||
| 194 | inline_node__delete(node); | ||
| 195 | return rows; | ||
| 196 | } | ||
| 197 | |||
| 147 | static int callchain_node__count_rows_rb_tree(struct callchain_node *node) | 198 | static int callchain_node__count_rows_rb_tree(struct callchain_node *node) |
| 148 | { | 199 | { |
| 149 | int n = 0; | 200 | int n = 0, inline_rows; |
| 150 | struct rb_node *nd; | 201 | struct rb_node *nd; |
| 151 | 202 | ||
| 152 | for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) { | 203 | for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) { |
| @@ -156,6 +207,13 @@ static int callchain_node__count_rows_rb_tree(struct callchain_node *node) | |||
| 156 | 207 | ||
| 157 | list_for_each_entry(chain, &child->val, list) { | 208 | list_for_each_entry(chain, &child->val, list) { |
| 158 | ++n; | 209 | ++n; |
| 210 | |||
| 211 | if (symbol_conf.inline_name) { | ||
| 212 | inline_rows = | ||
| 213 | callchain_list__inline_rows(chain); | ||
| 214 | n += inline_rows; | ||
| 215 | } | ||
| 216 | |||
| 159 | /* We need this because we may not have children */ | 217 | /* We need this because we may not have children */ |
| 160 | folded_sign = callchain_list__folded(chain); | 218 | folded_sign = callchain_list__folded(chain); |
| 161 | if (folded_sign == '+') | 219 | if (folded_sign == '+') |
| @@ -207,7 +265,7 @@ static int callchain_node__count_rows(struct callchain_node *node) | |||
| 207 | { | 265 | { |
| 208 | struct callchain_list *chain; | 266 | struct callchain_list *chain; |
| 209 | bool unfolded = false; | 267 | bool unfolded = false; |
| 210 | int n = 0; | 268 | int n = 0, inline_rows; |
| 211 | 269 | ||
| 212 | if (callchain_param.mode == CHAIN_FLAT) | 270 | if (callchain_param.mode == CHAIN_FLAT) |
| 213 | return callchain_node__count_flat_rows(node); | 271 | return callchain_node__count_flat_rows(node); |
| @@ -216,6 +274,11 @@ static int callchain_node__count_rows(struct callchain_node *node) | |||
| 216 | 274 | ||
| 217 | list_for_each_entry(chain, &node->val, list) { | 275 | list_for_each_entry(chain, &node->val, list) { |
| 218 | ++n; | 276 | ++n; |
| 277 | if (symbol_conf.inline_name) { | ||
| 278 | inline_rows = callchain_list__inline_rows(chain); | ||
| 279 | n += inline_rows; | ||
| 280 | } | ||
| 281 | |||
| 219 | unfolded = chain->unfolded; | 282 | unfolded = chain->unfolded; |
| 220 | } | 283 | } |
| 221 | 284 | ||
| @@ -362,6 +425,19 @@ static void hist_entry__init_have_children(struct hist_entry *he) | |||
| 362 | he->init_have_children = true; | 425 | he->init_have_children = true; |
| 363 | } | 426 | } |
| 364 | 427 | ||
| 428 | static void hist_entry_init_inline_node(struct hist_entry *he) | ||
| 429 | { | ||
| 430 | if (he->inline_node) | ||
| 431 | return; | ||
| 432 | |||
| 433 | he->inline_node = inline_node__create(he->ms.map, he->ip); | ||
| 434 | |||
| 435 | if (he->inline_node == NULL) | ||
| 436 | return; | ||
| 437 | |||
| 438 | he->has_children = true; | ||
| 439 | } | ||
| 440 | |||
| 365 | static bool hist_browser__toggle_fold(struct hist_browser *browser) | 441 | static bool hist_browser__toggle_fold(struct hist_browser *browser) |
| 366 | { | 442 | { |
| 367 | struct hist_entry *he = browser->he_selection; | 443 | struct hist_entry *he = browser->he_selection; |
| @@ -393,7 +469,12 @@ static bool hist_browser__toggle_fold(struct hist_browser *browser) | |||
| 393 | 469 | ||
| 394 | if (he->unfolded) { | 470 | if (he->unfolded) { |
| 395 | if (he->leaf) | 471 | if (he->leaf) |
| 396 | he->nr_rows = callchain__count_rows(&he->sorted_chain); | 472 | if (he->inline_node) |
| 473 | he->nr_rows = inline__count_rows( | ||
| 474 | he->inline_node); | ||
| 475 | else | ||
| 476 | he->nr_rows = callchain__count_rows( | ||
| 477 | &he->sorted_chain); | ||
| 397 | else | 478 | else |
| 398 | he->nr_rows = hierarchy_count_rows(browser, he, false); | 479 | he->nr_rows = hierarchy_count_rows(browser, he, false); |
| 399 | 480 | ||
| @@ -753,6 +834,71 @@ static bool hist_browser__check_dump_full(struct hist_browser *browser __maybe_u | |||
| 753 | 834 | ||
| 754 | #define LEVEL_OFFSET_STEP 3 | 835 | #define LEVEL_OFFSET_STEP 3 |
| 755 | 836 | ||
| 837 | static int hist_browser__show_inline(struct hist_browser *browser, | ||
| 838 | struct inline_node *node, | ||
| 839 | unsigned short row, | ||
| 840 | int offset) | ||
| 841 | { | ||
| 842 | struct inline_list *ilist; | ||
| 843 | char buf[1024]; | ||
| 844 | int color, width, first_row; | ||
| 845 | |||
| 846 | first_row = row; | ||
| 847 | width = browser->b.width - (LEVEL_OFFSET_STEP + 2); | ||
| 848 | list_for_each_entry(ilist, &node->val, list) { | ||
| 849 | if ((ilist->filename != NULL) || (ilist->funcname != NULL)) { | ||
| 850 | color = HE_COLORSET_NORMAL; | ||
| 851 | if (ui_browser__is_current_entry(&browser->b, row)) | ||
| 852 | color = HE_COLORSET_SELECTED; | ||
| 853 | |||
| 854 | if (callchain_param.key == CCKEY_ADDRESS || | ||
| 855 | callchain_param.key == CCKEY_SRCLINE) { | ||
| 856 | if (ilist->filename != NULL) | ||
| 857 | scnprintf(buf, sizeof(buf), | ||
| 858 | "%s:%d (inline)", | ||
| 859 | ilist->filename, | ||
| 860 | ilist->line_nr); | ||
| 861 | else | ||
| 862 | scnprintf(buf, sizeof(buf), "??"); | ||
| 863 | } else if (ilist->funcname != NULL) | ||
| 864 | scnprintf(buf, sizeof(buf), "%s (inline)", | ||
| 865 | ilist->funcname); | ||
| 866 | else if (ilist->filename != NULL) | ||
| 867 | scnprintf(buf, sizeof(buf), | ||
| 868 | "%s:%d (inline)", | ||
| 869 | ilist->filename, | ||
| 870 | ilist->line_nr); | ||
| 871 | else | ||
| 872 | scnprintf(buf, sizeof(buf), "??"); | ||
| 873 | |||
| 874 | ui_browser__set_color(&browser->b, color); | ||
| 875 | hist_browser__gotorc(browser, row, 0); | ||
| 876 | ui_browser__write_nstring(&browser->b, " ", | ||
| 877 | LEVEL_OFFSET_STEP + offset); | ||
| 878 | ui_browser__write_nstring(&browser->b, buf, width); | ||
| 879 | row++; | ||
| 880 | } | ||
| 881 | } | ||
| 882 | |||
| 883 | return row - first_row; | ||
| 884 | } | ||
| 885 | |||
| 886 | static size_t show_inline_list(struct hist_browser *browser, struct map *map, | ||
| 887 | u64 ip, int row, int offset) | ||
| 888 | { | ||
| 889 | struct inline_node *node; | ||
| 890 | int ret; | ||
| 891 | |||
| 892 | node = inline_node__create(map, ip); | ||
| 893 | if (node == NULL) | ||
| 894 | return 0; | ||
| 895 | |||
| 896 | ret = hist_browser__show_inline(browser, node, row, offset); | ||
| 897 | |||
| 898 | inline_node__delete(node); | ||
| 899 | return ret; | ||
| 900 | } | ||
| 901 | |||
| 756 | static int hist_browser__show_callchain_list(struct hist_browser *browser, | 902 | static int hist_browser__show_callchain_list(struct hist_browser *browser, |
| 757 | struct callchain_node *node, | 903 | struct callchain_node *node, |
| 758 | struct callchain_list *chain, | 904 | struct callchain_list *chain, |
| @@ -764,6 +910,7 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser, | |||
| 764 | char bf[1024], *alloc_str; | 910 | char bf[1024], *alloc_str; |
| 765 | char buf[64], *alloc_str2; | 911 | char buf[64], *alloc_str2; |
| 766 | const char *str; | 912 | const char *str; |
| 913 | int inline_rows = 0, ret = 1; | ||
| 767 | 914 | ||
| 768 | if (arg->row_offset != 0) { | 915 | if (arg->row_offset != 0) { |
| 769 | arg->row_offset--; | 916 | arg->row_offset--; |
| @@ -801,10 +948,15 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser, | |||
| 801 | } | 948 | } |
| 802 | 949 | ||
| 803 | print(browser, chain, str, offset, row, arg); | 950 | print(browser, chain, str, offset, row, arg); |
| 804 | |||
| 805 | free(alloc_str); | 951 | free(alloc_str); |
| 806 | free(alloc_str2); | 952 | free(alloc_str2); |
| 807 | return 1; | 953 | |
| 954 | if (symbol_conf.inline_name) { | ||
| 955 | inline_rows = show_inline_list(browser, chain->ms.map, | ||
| 956 | chain->ip, row + 1, offset); | ||
| 957 | } | ||
| 958 | |||
| 959 | return ret + inline_rows; | ||
| 808 | } | 960 | } |
| 809 | 961 | ||
| 810 | static bool check_percent_display(struct rb_node *node, u64 parent_total) | 962 | static bool check_percent_display(struct rb_node *node, u64 parent_total) |
| @@ -1228,6 +1380,12 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
| 1228 | folded_sign = hist_entry__folded(entry); | 1380 | folded_sign = hist_entry__folded(entry); |
| 1229 | } | 1381 | } |
| 1230 | 1382 | ||
| 1383 | if (symbol_conf.inline_name && | ||
| 1384 | (!entry->has_children)) { | ||
| 1385 | hist_entry_init_inline_node(entry); | ||
| 1386 | folded_sign = hist_entry__folded(entry); | ||
| 1387 | } | ||
| 1388 | |||
| 1231 | if (row_offset == 0) { | 1389 | if (row_offset == 0) { |
| 1232 | struct hpp_arg arg = { | 1390 | struct hpp_arg arg = { |
| 1233 | .b = &browser->b, | 1391 | .b = &browser->b, |
| @@ -1259,7 +1417,8 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
| 1259 | } | 1417 | } |
| 1260 | 1418 | ||
| 1261 | if (first) { | 1419 | if (first) { |
| 1262 | if (symbol_conf.use_callchain) { | 1420 | if (symbol_conf.use_callchain || |
| 1421 | symbol_conf.inline_name) { | ||
| 1263 | ui_browser__printf(&browser->b, "%c ", folded_sign); | 1422 | ui_browser__printf(&browser->b, "%c ", folded_sign); |
| 1264 | width -= 2; | 1423 | width -= 2; |
| 1265 | } | 1424 | } |
| @@ -1301,8 +1460,14 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
| 1301 | .is_current_entry = current_entry, | 1460 | .is_current_entry = current_entry, |
| 1302 | }; | 1461 | }; |
| 1303 | 1462 | ||
| 1304 | printed += hist_browser__show_callchain(browser, entry, 1, row, | 1463 | if (entry->inline_node) |
| 1305 | hist_browser__show_callchain_entry, &arg, | 1464 | printed += hist_browser__show_inline(browser, |
| 1465 | entry->inline_node, row, 0); | ||
| 1466 | else | ||
| 1467 | printed += hist_browser__show_callchain(browser, | ||
| 1468 | entry, 1, row, | ||
| 1469 | hist_browser__show_callchain_entry, | ||
| 1470 | &arg, | ||
| 1306 | hist_browser__check_output_full); | 1471 | hist_browser__check_output_full); |
| 1307 | } | 1472 | } |
| 1308 | 1473 | ||
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 668f4aecf2e6..d52d5f64ea89 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
| @@ -17,6 +17,67 @@ static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) | |||
| 17 | return ret; | 17 | return ret; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | static size_t inline__fprintf(struct map *map, u64 ip, int left_margin, | ||
| 21 | int depth, int depth_mask, FILE *fp) | ||
| 22 | { | ||
| 23 | struct dso *dso; | ||
| 24 | struct inline_node *node; | ||
| 25 | struct inline_list *ilist; | ||
| 26 | int ret = 0, i; | ||
| 27 | |||
| 28 | if (map == NULL) | ||
| 29 | return 0; | ||
| 30 | |||
| 31 | dso = map->dso; | ||
| 32 | if (dso == NULL) | ||
| 33 | return 0; | ||
| 34 | |||
| 35 | if (dso->kernel != DSO_TYPE_USER) | ||
| 36 | return 0; | ||
| 37 | |||
| 38 | node = dso__parse_addr_inlines(dso, | ||
| 39 | map__rip_2objdump(map, ip)); | ||
| 40 | if (node == NULL) | ||
| 41 | return 0; | ||
| 42 | |||
| 43 | list_for_each_entry(ilist, &node->val, list) { | ||
| 44 | if ((ilist->filename != NULL) || (ilist->funcname != NULL)) { | ||
| 45 | ret += callchain__fprintf_left_margin(fp, left_margin); | ||
| 46 | |||
| 47 | for (i = 0; i < depth; i++) { | ||
| 48 | if (depth_mask & (1 << i)) | ||
| 49 | ret += fprintf(fp, "|"); | ||
| 50 | else | ||
| 51 | ret += fprintf(fp, " "); | ||
| 52 | ret += fprintf(fp, " "); | ||
| 53 | } | ||
| 54 | |||
| 55 | if (callchain_param.key == CCKEY_ADDRESS || | ||
| 56 | callchain_param.key == CCKEY_SRCLINE) { | ||
| 57 | if (ilist->filename != NULL) | ||
| 58 | ret += fprintf(fp, "%s:%d (inline)", | ||
| 59 | ilist->filename, | ||
| 60 | ilist->line_nr); | ||
| 61 | else | ||
| 62 | ret += fprintf(fp, "??"); | ||
| 63 | } else if (ilist->funcname != NULL) | ||
| 64 | ret += fprintf(fp, "%s (inline)", | ||
| 65 | ilist->funcname); | ||
| 66 | else if (ilist->filename != NULL) | ||
| 67 | ret += fprintf(fp, "%s:%d (inline)", | ||
| 68 | ilist->filename, | ||
| 69 | ilist->line_nr); | ||
| 70 | else | ||
| 71 | ret += fprintf(fp, "??"); | ||
| 72 | |||
| 73 | ret += fprintf(fp, "\n"); | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | inline_node__delete(node); | ||
| 78 | return ret; | ||
| 79 | } | ||
| 80 | |||
| 20 | static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask, | 81 | static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask, |
| 21 | int left_margin) | 82 | int left_margin) |
| 22 | { | 83 | { |
| @@ -78,6 +139,10 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node, | |||
| 78 | fputs(str, fp); | 139 | fputs(str, fp); |
| 79 | fputc('\n', fp); | 140 | fputc('\n', fp); |
| 80 | free(alloc_str); | 141 | free(alloc_str); |
| 142 | |||
| 143 | if (symbol_conf.inline_name) | ||
| 144 | ret += inline__fprintf(chain->ms.map, chain->ip, | ||
| 145 | left_margin, depth, depth_mask, fp); | ||
| 81 | return ret; | 146 | return ret; |
| 82 | } | 147 | } |
| 83 | 148 | ||
| @@ -229,6 +294,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, | |||
| 229 | if (!i++ && field_order == NULL && | 294 | if (!i++ && field_order == NULL && |
| 230 | sort_order && !prefixcmp(sort_order, "sym")) | 295 | sort_order && !prefixcmp(sort_order, "sym")) |
| 231 | continue; | 296 | continue; |
| 297 | |||
| 232 | if (!printed) { | 298 | if (!printed) { |
| 233 | ret += callchain__fprintf_left_margin(fp, left_margin); | 299 | ret += callchain__fprintf_left_margin(fp, left_margin); |
| 234 | ret += fprintf(fp, "|\n"); | 300 | ret += fprintf(fp, "|\n"); |
| @@ -251,6 +317,13 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, | |||
| 251 | 317 | ||
| 252 | if (++entries_printed == callchain_param.print_limit) | 318 | if (++entries_printed == callchain_param.print_limit) |
| 253 | break; | 319 | break; |
| 320 | |||
| 321 | if (symbol_conf.inline_name) | ||
| 322 | ret += inline__fprintf(chain->ms.map, | ||
| 323 | chain->ip, | ||
| 324 | left_margin, | ||
| 325 | 0, 0, | ||
| 326 | fp); | ||
| 254 | } | 327 | } |
| 255 | root = &cnode->rb_root; | 328 | root = &cnode->rb_root; |
| 256 | } | 329 | } |
| @@ -529,6 +602,8 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, | |||
| 529 | bool use_callchain) | 602 | bool use_callchain) |
| 530 | { | 603 | { |
| 531 | int ret; | 604 | int ret; |
| 605 | int callchain_ret = 0; | ||
| 606 | int inline_ret = 0; | ||
| 532 | struct perf_hpp hpp = { | 607 | struct perf_hpp hpp = { |
| 533 | .buf = bf, | 608 | .buf = bf, |
| 534 | .size = size, | 609 | .size = size, |
| @@ -547,7 +622,16 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, | |||
| 547 | ret = fprintf(fp, "%s\n", bf); | 622 | ret = fprintf(fp, "%s\n", bf); |
| 548 | 623 | ||
| 549 | if (use_callchain) | 624 | if (use_callchain) |
| 550 | ret += hist_entry_callchain__fprintf(he, total_period, 0, fp); | 625 | callchain_ret = hist_entry_callchain__fprintf(he, total_period, |
| 626 | 0, fp); | ||
| 627 | |||
| 628 | if (callchain_ret == 0 && symbol_conf.inline_name) { | ||
| 629 | inline_ret = inline__fprintf(he->ms.map, he->ip, 0, 0, 0, fp); | ||
| 630 | ret += inline_ret; | ||
| 631 | if (inline_ret > 0) | ||
| 632 | ret += fprintf(fp, "\n"); | ||
| 633 | } else | ||
| 634 | ret += callchain_ret; | ||
| 551 | 635 | ||
| 552 | return ret; | 636 | return ret; |
| 553 | } | 637 | } |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 22cd1dbe724b..11af5f0d56cc 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
| @@ -1307,6 +1307,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil | |||
| 1307 | { | 1307 | { |
| 1308 | char linkname[PATH_MAX]; | 1308 | char linkname[PATH_MAX]; |
| 1309 | char *build_id_filename; | 1309 | char *build_id_filename; |
| 1310 | char *build_id_path = NULL; | ||
| 1310 | 1311 | ||
| 1311 | if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && | 1312 | if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && |
| 1312 | !dso__is_kcore(dso)) | 1313 | !dso__is_kcore(dso)) |
| @@ -1322,8 +1323,14 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil | |||
| 1322 | goto fallback; | 1323 | goto fallback; |
| 1323 | } | 1324 | } |
| 1324 | 1325 | ||
| 1326 | build_id_path = strdup(filename); | ||
| 1327 | if (!build_id_path) | ||
| 1328 | return -1; | ||
| 1329 | |||
| 1330 | dirname(build_id_path); | ||
| 1331 | |||
| 1325 | if (dso__is_kcore(dso) || | 1332 | if (dso__is_kcore(dso) || |
| 1326 | readlink(filename, linkname, sizeof(linkname)) < 0 || | 1333 | readlink(build_id_path, linkname, sizeof(linkname)) < 0 || |
| 1327 | strstr(linkname, DSO__NAME_KALLSYMS) || | 1334 | strstr(linkname, DSO__NAME_KALLSYMS) || |
| 1328 | access(filename, R_OK)) { | 1335 | access(filename, R_OK)) { |
| 1329 | fallback: | 1336 | fallback: |
| @@ -1335,6 +1342,7 @@ fallback: | |||
| 1335 | __symbol__join_symfs(filename, filename_size, dso->long_name); | 1342 | __symbol__join_symfs(filename, filename_size, dso->long_name); |
| 1336 | } | 1343 | } |
| 1337 | 1344 | ||
| 1345 | free(build_id_path); | ||
| 1338 | return 0; | 1346 | return 0; |
| 1339 | } | 1347 | } |
| 1340 | 1348 | ||
| @@ -1663,18 +1671,23 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
| 1663 | src_line->nr_pcnt = nr_pcnt; | 1671 | src_line->nr_pcnt = nr_pcnt; |
| 1664 | 1672 | ||
| 1665 | for (k = 0; k < nr_pcnt; k++) { | 1673 | for (k = 0; k < nr_pcnt; k++) { |
| 1674 | double percent = 0.0; | ||
| 1675 | |||
| 1666 | h = annotation__histogram(notes, evidx + k); | 1676 | h = annotation__histogram(notes, evidx + k); |
| 1667 | src_line->samples[k].percent = 100.0 * h->addr[i] / h->sum; | 1677 | if (h->sum) |
| 1678 | percent = 100.0 * h->addr[i] / h->sum; | ||
| 1668 | 1679 | ||
| 1669 | if (src_line->samples[k].percent > percent_max) | 1680 | if (percent > percent_max) |
| 1670 | percent_max = src_line->samples[k].percent; | 1681 | percent_max = percent; |
| 1682 | src_line->samples[k].percent = percent; | ||
| 1671 | } | 1683 | } |
| 1672 | 1684 | ||
| 1673 | if (percent_max <= 0.5) | 1685 | if (percent_max <= 0.5) |
| 1674 | goto next; | 1686 | goto next; |
| 1675 | 1687 | ||
| 1676 | offset = start + i; | 1688 | offset = start + i; |
| 1677 | src_line->path = get_srcline(map->dso, offset, NULL, false); | 1689 | src_line->path = get_srcline(map->dso, offset, NULL, |
| 1690 | false, true); | ||
| 1678 | insert_source_line(&tmp_root, src_line); | 1691 | insert_source_line(&tmp_root, src_line); |
| 1679 | 1692 | ||
| 1680 | next: | 1693 | next: |
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index c5a6e0b12452..78bd632f144d 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c | |||
| @@ -1826,7 +1826,7 @@ static int addr_filter__resolve_kernel_syms(struct addr_filter *filt) | |||
| 1826 | filt->addr = start; | 1826 | filt->addr = start; |
| 1827 | if (filt->range && !filt->size && !filt->sym_to) { | 1827 | if (filt->range && !filt->size && !filt->sym_to) { |
| 1828 | filt->size = size; | 1828 | filt->size = size; |
| 1829 | no_size = !!size; | 1829 | no_size = !size; |
| 1830 | } | 1830 | } |
| 1831 | } | 1831 | } |
| 1832 | 1832 | ||
| @@ -1840,7 +1840,7 @@ static int addr_filter__resolve_kernel_syms(struct addr_filter *filt) | |||
| 1840 | if (err) | 1840 | if (err) |
| 1841 | return err; | 1841 | return err; |
| 1842 | filt->size = start + size - filt->addr; | 1842 | filt->size = start + size - filt->addr; |
| 1843 | no_size = !!size; | 1843 | no_size = !size; |
| 1844 | } | 1844 | } |
| 1845 | 1845 | ||
| 1846 | /* The very last symbol in kallsyms does not imply a particular size */ | 1846 | /* The very last symbol in kallsyms does not imply a particular size */ |
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e528c40739cc..33af67530d30 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
| @@ -182,13 +182,17 @@ char *build_id_cache__origname(const char *sbuild_id) | |||
| 182 | char buf[PATH_MAX]; | 182 | char buf[PATH_MAX]; |
| 183 | char *ret = NULL, *p; | 183 | char *ret = NULL, *p; |
| 184 | size_t offs = 5; /* == strlen("../..") */ | 184 | size_t offs = 5; /* == strlen("../..") */ |
| 185 | ssize_t len; | ||
| 185 | 186 | ||
| 186 | linkname = build_id_cache__linkname(sbuild_id, NULL, 0); | 187 | linkname = build_id_cache__linkname(sbuild_id, NULL, 0); |
| 187 | if (!linkname) | 188 | if (!linkname) |
| 188 | return NULL; | 189 | return NULL; |
| 189 | 190 | ||
| 190 | if (readlink(linkname, buf, PATH_MAX) < 0) | 191 | len = readlink(linkname, buf, sizeof(buf) - 1); |
| 192 | if (len <= 0) | ||
| 191 | goto out; | 193 | goto out; |
| 194 | buf[len] = '\0'; | ||
| 195 | |||
| 192 | /* The link should be "../..<origpath>/<sbuild_id>" */ | 196 | /* The link should be "../..<origpath>/<sbuild_id>" */ |
| 193 | p = strrchr(buf, '/'); /* Cut off the "/<sbuild_id>" */ | 197 | p = strrchr(buf, '/'); /* Cut off the "/<sbuild_id>" */ |
| 194 | if (p && (p > buf + offs)) { | 198 | if (p && (p > buf + offs)) { |
| @@ -690,7 +694,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, | |||
| 690 | err = 0; | 694 | err = 0; |
| 691 | 695 | ||
| 692 | /* Update SDT cache : error is just warned */ | 696 | /* Update SDT cache : error is just warned */ |
| 693 | if (build_id_cache__add_sdt_cache(sbuild_id, realname) < 0) | 697 | if (realname && build_id_cache__add_sdt_cache(sbuild_id, realname) < 0) |
| 694 | pr_debug4("Failed to update/scan SDT cache for %s\n", realname); | 698 | pr_debug4("Failed to update/scan SDT cache for %s\n", realname); |
| 695 | 699 | ||
| 696 | out_free: | 700 | out_free: |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index aba953421a03..d78776a20e80 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
| @@ -80,6 +80,10 @@ static int parse_callchain_sort_key(const char *value) | |||
| 80 | callchain_param.key = CCKEY_ADDRESS; | 80 | callchain_param.key = CCKEY_ADDRESS; |
| 81 | return 0; | 81 | return 0; |
| 82 | } | 82 | } |
| 83 | if (!strncmp(value, "srcline", strlen(value))) { | ||
| 84 | callchain_param.key = CCKEY_SRCLINE; | ||
| 85 | return 0; | ||
| 86 | } | ||
| 83 | if (!strncmp(value, "branch", strlen(value))) { | 87 | if (!strncmp(value, "branch", strlen(value))) { |
| 84 | callchain_param.branch_callstack = 1; | 88 | callchain_param.branch_callstack = 1; |
| 85 | return 0; | 89 | return 0; |
| @@ -510,14 +514,51 @@ enum match_result { | |||
| 510 | MATCH_GT, | 514 | MATCH_GT, |
| 511 | }; | 515 | }; |
| 512 | 516 | ||
| 517 | static enum match_result match_chain_srcline(struct callchain_cursor_node *node, | ||
| 518 | struct callchain_list *cnode) | ||
| 519 | { | ||
| 520 | char *left = get_srcline(cnode->ms.map->dso, | ||
| 521 | map__rip_2objdump(cnode->ms.map, cnode->ip), | ||
| 522 | cnode->ms.sym, true, false); | ||
| 523 | char *right = get_srcline(node->map->dso, | ||
| 524 | map__rip_2objdump(node->map, node->ip), | ||
| 525 | node->sym, true, false); | ||
| 526 | enum match_result ret = MATCH_EQ; | ||
| 527 | int cmp; | ||
| 528 | |||
| 529 | if (left && right) | ||
| 530 | cmp = strcmp(left, right); | ||
| 531 | else if (!left && right) | ||
| 532 | cmp = 1; | ||
| 533 | else if (left && !right) | ||
| 534 | cmp = -1; | ||
| 535 | else if (cnode->ip == node->ip) | ||
| 536 | cmp = 0; | ||
| 537 | else | ||
| 538 | cmp = (cnode->ip < node->ip) ? -1 : 1; | ||
| 539 | |||
| 540 | if (cmp != 0) | ||
| 541 | ret = cmp < 0 ? MATCH_LT : MATCH_GT; | ||
| 542 | |||
| 543 | free_srcline(left); | ||
| 544 | free_srcline(right); | ||
| 545 | return ret; | ||
| 546 | } | ||
| 547 | |||
| 513 | static enum match_result match_chain(struct callchain_cursor_node *node, | 548 | static enum match_result match_chain(struct callchain_cursor_node *node, |
| 514 | struct callchain_list *cnode) | 549 | struct callchain_list *cnode) |
| 515 | { | 550 | { |
| 516 | struct symbol *sym = node->sym; | 551 | struct symbol *sym = node->sym; |
| 517 | u64 left, right; | 552 | u64 left, right; |
| 518 | 553 | ||
| 519 | if (cnode->ms.sym && sym && | 554 | if (callchain_param.key == CCKEY_SRCLINE) { |
| 520 | callchain_param.key == CCKEY_FUNCTION) { | 555 | enum match_result match = match_chain_srcline(node, cnode); |
| 556 | |||
| 557 | if (match != MATCH_ERROR) | ||
| 558 | return match; | ||
| 559 | } | ||
| 560 | |||
| 561 | if (cnode->ms.sym && sym && callchain_param.key == CCKEY_FUNCTION) { | ||
| 521 | left = cnode->ms.sym->start; | 562 | left = cnode->ms.sym->start; |
| 522 | right = sym->start; | 563 | right = sym->start; |
| 523 | } else { | 564 | } else { |
| @@ -911,15 +952,16 @@ out: | |||
| 911 | char *callchain_list__sym_name(struct callchain_list *cl, | 952 | char *callchain_list__sym_name(struct callchain_list *cl, |
| 912 | char *bf, size_t bfsize, bool show_dso) | 953 | char *bf, size_t bfsize, bool show_dso) |
| 913 | { | 954 | { |
| 955 | bool show_addr = callchain_param.key == CCKEY_ADDRESS; | ||
| 956 | bool show_srcline = show_addr || callchain_param.key == CCKEY_SRCLINE; | ||
| 914 | int printed; | 957 | int printed; |
| 915 | 958 | ||
| 916 | if (cl->ms.sym) { | 959 | if (cl->ms.sym) { |
| 917 | if (callchain_param.key == CCKEY_ADDRESS && | 960 | if (show_srcline && cl->ms.map && !cl->srcline) |
| 918 | cl->ms.map && !cl->srcline) | ||
| 919 | cl->srcline = get_srcline(cl->ms.map->dso, | 961 | cl->srcline = get_srcline(cl->ms.map->dso, |
| 920 | map__rip_2objdump(cl->ms.map, | 962 | map__rip_2objdump(cl->ms.map, |
| 921 | cl->ip), | 963 | cl->ip), |
| 922 | cl->ms.sym, false); | 964 | cl->ms.sym, false, show_addr); |
| 923 | if (cl->srcline) | 965 | if (cl->srcline) |
| 924 | printed = scnprintf(bf, bfsize, "%s %s", | 966 | printed = scnprintf(bf, bfsize, "%s %s", |
| 925 | cl->ms.sym->name, cl->srcline); | 967 | cl->ms.sym->name, cl->srcline); |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 4f4b60f1558a..c56c23dbbf72 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
| @@ -77,7 +77,8 @@ typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_root *, | |||
| 77 | 77 | ||
| 78 | enum chain_key { | 78 | enum chain_key { |
| 79 | CCKEY_FUNCTION, | 79 | CCKEY_FUNCTION, |
| 80 | CCKEY_ADDRESS | 80 | CCKEY_ADDRESS, |
| 81 | CCKEY_SRCLINE | ||
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 83 | enum chain_value { | 84 | enum chain_value { |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 05714d548584..ef09f26e67da 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -370,15 +370,11 @@ static int write_cmdline(int fd, struct perf_header *h __maybe_unused, | |||
| 370 | struct perf_evlist *evlist __maybe_unused) | 370 | struct perf_evlist *evlist __maybe_unused) |
| 371 | { | 371 | { |
| 372 | char buf[MAXPATHLEN]; | 372 | char buf[MAXPATHLEN]; |
| 373 | char proc[32]; | ||
| 374 | u32 n; | 373 | u32 n; |
| 375 | int i, ret; | 374 | int i, ret; |
| 376 | 375 | ||
| 377 | /* | 376 | /* actual path to perf binary */ |
| 378 | * actual atual path to perf binary | 377 | ret = readlink("/proc/self/exe", buf, sizeof(buf) - 1); |
| 379 | */ | ||
| 380 | sprintf(proc, "/proc/%d/exe", getpid()); | ||
| 381 | ret = readlink(proc, buf, sizeof(buf)); | ||
| 382 | if (ret <= 0) | 378 | if (ret <= 0) |
| 383 | return -1; | 379 | return -1; |
| 384 | 380 | ||
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index e3b38f629504..3c4d4d00cb2c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -1136,6 +1136,11 @@ void hist_entry__delete(struct hist_entry *he) | |||
| 1136 | zfree(&he->mem_info); | 1136 | zfree(&he->mem_info); |
| 1137 | } | 1137 | } |
| 1138 | 1138 | ||
| 1139 | if (he->inline_node) { | ||
| 1140 | inline_node__delete(he->inline_node); | ||
| 1141 | he->inline_node = NULL; | ||
| 1142 | } | ||
| 1143 | |||
| 1139 | zfree(&he->stat_acc); | 1144 | zfree(&he->stat_acc); |
| 1140 | free_srcline(he->srcline); | 1145 | free_srcline(he->srcline); |
| 1141 | if (he->srcfile && he->srcfile[0]) | 1146 | if (he->srcfile && he->srcfile[0]) |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 1d9ebcf9e38e..c1870ac365a3 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
| @@ -405,7 +405,8 @@ int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, | |||
| 405 | 405 | ||
| 406 | if (map && map->dso) { | 406 | if (map && map->dso) { |
| 407 | srcline = get_srcline(map->dso, | 407 | srcline = get_srcline(map->dso, |
| 408 | map__rip_2objdump(map, addr), NULL, true); | 408 | map__rip_2objdump(map, addr), NULL, |
| 409 | true, true); | ||
| 409 | if (srcline != SRCLINE_UNKNOWN) | 410 | if (srcline != SRCLINE_UNKNOWN) |
| 410 | ret = fprintf(fp, "%s%s", prefix, srcline); | 411 | ret = fprintf(fp, "%s%s", prefix, srcline); |
| 411 | free_srcline(srcline); | 412 | free_srcline(srcline); |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 8b0d4e39f640..73f3ec1cf2a0 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
| @@ -323,7 +323,7 @@ char *hist_entry__get_srcline(struct hist_entry *he) | |||
| 323 | return SRCLINE_UNKNOWN; | 323 | return SRCLINE_UNKNOWN; |
| 324 | 324 | ||
| 325 | return get_srcline(map->dso, map__rip_2objdump(map, he->ip), | 325 | return get_srcline(map->dso, map__rip_2objdump(map, he->ip), |
| 326 | he->ms.sym, true); | 326 | he->ms.sym, true, true); |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | static int64_t | 329 | static int64_t |
| @@ -366,7 +366,8 @@ sort__srcline_from_cmp(struct hist_entry *left, struct hist_entry *right) | |||
| 366 | left->branch_info->srcline_from = get_srcline(map->dso, | 366 | left->branch_info->srcline_from = get_srcline(map->dso, |
| 367 | map__rip_2objdump(map, | 367 | map__rip_2objdump(map, |
| 368 | left->branch_info->from.al_addr), | 368 | left->branch_info->from.al_addr), |
| 369 | left->branch_info->from.sym, true); | 369 | left->branch_info->from.sym, |
| 370 | true, true); | ||
| 370 | } | 371 | } |
| 371 | if (!right->branch_info->srcline_from) { | 372 | if (!right->branch_info->srcline_from) { |
| 372 | struct map *map = right->branch_info->from.map; | 373 | struct map *map = right->branch_info->from.map; |
| @@ -376,7 +377,8 @@ sort__srcline_from_cmp(struct hist_entry *left, struct hist_entry *right) | |||
| 376 | right->branch_info->srcline_from = get_srcline(map->dso, | 377 | right->branch_info->srcline_from = get_srcline(map->dso, |
| 377 | map__rip_2objdump(map, | 378 | map__rip_2objdump(map, |
| 378 | right->branch_info->from.al_addr), | 379 | right->branch_info->from.al_addr), |
| 379 | right->branch_info->from.sym, true); | 380 | right->branch_info->from.sym, |
| 381 | true, true); | ||
| 380 | } | 382 | } |
| 381 | return strcmp(right->branch_info->srcline_from, left->branch_info->srcline_from); | 383 | return strcmp(right->branch_info->srcline_from, left->branch_info->srcline_from); |
| 382 | } | 384 | } |
| @@ -407,7 +409,8 @@ sort__srcline_to_cmp(struct hist_entry *left, struct hist_entry *right) | |||
| 407 | left->branch_info->srcline_to = get_srcline(map->dso, | 409 | left->branch_info->srcline_to = get_srcline(map->dso, |
| 408 | map__rip_2objdump(map, | 410 | map__rip_2objdump(map, |
| 409 | left->branch_info->to.al_addr), | 411 | left->branch_info->to.al_addr), |
| 410 | left->branch_info->from.sym, true); | 412 | left->branch_info->from.sym, |
| 413 | true, true); | ||
| 411 | } | 414 | } |
| 412 | if (!right->branch_info->srcline_to) { | 415 | if (!right->branch_info->srcline_to) { |
| 413 | struct map *map = right->branch_info->to.map; | 416 | struct map *map = right->branch_info->to.map; |
| @@ -417,7 +420,8 @@ sort__srcline_to_cmp(struct hist_entry *left, struct hist_entry *right) | |||
| 417 | right->branch_info->srcline_to = get_srcline(map->dso, | 420 | right->branch_info->srcline_to = get_srcline(map->dso, |
| 418 | map__rip_2objdump(map, | 421 | map__rip_2objdump(map, |
| 419 | right->branch_info->to.al_addr), | 422 | right->branch_info->to.al_addr), |
| 420 | right->branch_info->to.sym, true); | 423 | right->branch_info->to.sym, |
| 424 | true, true); | ||
| 421 | } | 425 | } |
| 422 | return strcmp(right->branch_info->srcline_to, left->branch_info->srcline_to); | 426 | return strcmp(right->branch_info->srcline_to, left->branch_info->srcline_to); |
| 423 | } | 427 | } |
| @@ -448,7 +452,7 @@ static char *hist_entry__get_srcfile(struct hist_entry *e) | |||
| 448 | return no_srcfile; | 452 | return no_srcfile; |
| 449 | 453 | ||
| 450 | sf = __get_srcline(map->dso, map__rip_2objdump(map, e->ip), | 454 | sf = __get_srcline(map->dso, map__rip_2objdump(map, e->ip), |
| 451 | e->ms.sym, false, true); | 455 | e->ms.sym, false, true, true); |
| 452 | if (!strcmp(sf, SRCLINE_UNKNOWN)) | 456 | if (!strcmp(sf, SRCLINE_UNKNOWN)) |
| 453 | return no_srcfile; | 457 | return no_srcfile; |
| 454 | p = strchr(sf, ':'); | 458 | p = strchr(sf, ':'); |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index baf20a399f34..e35fb186d048 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
| @@ -128,6 +128,7 @@ struct hist_entry { | |||
| 128 | }; | 128 | }; |
| 129 | char *srcline; | 129 | char *srcline; |
| 130 | char *srcfile; | 130 | char *srcfile; |
| 131 | struct inline_node *inline_node; | ||
| 131 | struct symbol *parent; | 132 | struct symbol *parent; |
| 132 | struct branch_info *branch_info; | 133 | struct branch_info *branch_info; |
| 133 | struct hists *hists; | 134 | struct hists *hists; |
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index b4db3f48e3b0..778ccb5d99d1 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c | |||
| @@ -7,11 +7,58 @@ | |||
| 7 | #include "util/dso.h" | 7 | #include "util/dso.h" |
| 8 | #include "util/util.h" | 8 | #include "util/util.h" |
| 9 | #include "util/debug.h" | 9 | #include "util/debug.h" |
| 10 | #include "util/callchain.h" | ||
| 10 | 11 | ||
| 11 | #include "symbol.h" | 12 | #include "symbol.h" |
| 12 | 13 | ||
| 13 | bool srcline_full_filename; | 14 | bool srcline_full_filename; |
| 14 | 15 | ||
| 16 | static const char *dso__name(struct dso *dso) | ||
| 17 | { | ||
| 18 | const char *dso_name; | ||
| 19 | |||
| 20 | if (dso->symsrc_filename) | ||
| 21 | dso_name = dso->symsrc_filename; | ||
| 22 | else | ||
| 23 | dso_name = dso->long_name; | ||
| 24 | |||
| 25 | if (dso_name[0] == '[') | ||
| 26 | return NULL; | ||
| 27 | |||
| 28 | if (!strncmp(dso_name, "/tmp/perf-", 10)) | ||
| 29 | return NULL; | ||
| 30 | |||
| 31 | return dso_name; | ||
| 32 | } | ||
| 33 | |||
| 34 | static int inline_list__append(char *filename, char *funcname, int line_nr, | ||
| 35 | struct inline_node *node, struct dso *dso) | ||
| 36 | { | ||
| 37 | struct inline_list *ilist; | ||
| 38 | char *demangled; | ||
| 39 | |||
| 40 | ilist = zalloc(sizeof(*ilist)); | ||
| 41 | if (ilist == NULL) | ||
| 42 | return -1; | ||
| 43 | |||
| 44 | ilist->filename = filename; | ||
| 45 | ilist->line_nr = line_nr; | ||
| 46 | |||
| 47 | if (dso != NULL) { | ||
| 48 | demangled = dso__demangle_sym(dso, 0, funcname); | ||
| 49 | if (demangled == NULL) { | ||
| 50 | ilist->funcname = funcname; | ||
| 51 | } else { | ||
| 52 | ilist->funcname = demangled; | ||
| 53 | free(funcname); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | list_add_tail(&ilist->list, &node->val); | ||
| 58 | |||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 15 | #ifdef HAVE_LIBBFD_SUPPORT | 62 | #ifdef HAVE_LIBBFD_SUPPORT |
| 16 | 63 | ||
| 17 | /* | 64 | /* |
| @@ -151,9 +198,17 @@ static void addr2line_cleanup(struct a2l_data *a2l) | |||
| 151 | 198 | ||
| 152 | #define MAX_INLINE_NEST 1024 | 199 | #define MAX_INLINE_NEST 1024 |
| 153 | 200 | ||
| 201 | static void inline_list__reverse(struct inline_node *node) | ||
| 202 | { | ||
| 203 | struct inline_list *ilist, *n; | ||
| 204 | |||
| 205 | list_for_each_entry_safe_reverse(ilist, n, &node->val, list) | ||
| 206 | list_move_tail(&ilist->list, &node->val); | ||
| 207 | } | ||
| 208 | |||
| 154 | static int addr2line(const char *dso_name, u64 addr, | 209 | static int addr2line(const char *dso_name, u64 addr, |
| 155 | char **file, unsigned int *line, struct dso *dso, | 210 | char **file, unsigned int *line, struct dso *dso, |
| 156 | bool unwind_inlines) | 211 | bool unwind_inlines, struct inline_node *node) |
| 157 | { | 212 | { |
| 158 | int ret = 0; | 213 | int ret = 0; |
| 159 | struct a2l_data *a2l = dso->a2l; | 214 | struct a2l_data *a2l = dso->a2l; |
| @@ -178,8 +233,21 @@ static int addr2line(const char *dso_name, u64 addr, | |||
| 178 | 233 | ||
| 179 | while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, | 234 | while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, |
| 180 | &a2l->funcname, &a2l->line) && | 235 | &a2l->funcname, &a2l->line) && |
| 181 | cnt++ < MAX_INLINE_NEST) | 236 | cnt++ < MAX_INLINE_NEST) { |
| 182 | ; | 237 | |
| 238 | if (node != NULL) { | ||
| 239 | if (inline_list__append(strdup(a2l->filename), | ||
| 240 | strdup(a2l->funcname), | ||
| 241 | a2l->line, node, | ||
| 242 | dso) != 0) | ||
| 243 | return 0; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | if ((node != NULL) && | ||
| 248 | (callchain_param.order != ORDER_CALLEE)) { | ||
| 249 | inline_list__reverse(node); | ||
| 250 | } | ||
| 183 | } | 251 | } |
| 184 | 252 | ||
| 185 | if (a2l->found && a2l->filename) { | 253 | if (a2l->found && a2l->filename) { |
| @@ -205,18 +273,68 @@ void dso__free_a2l(struct dso *dso) | |||
| 205 | dso->a2l = NULL; | 273 | dso->a2l = NULL; |
| 206 | } | 274 | } |
| 207 | 275 | ||
| 276 | static struct inline_node *addr2inlines(const char *dso_name, u64 addr, | ||
| 277 | struct dso *dso) | ||
| 278 | { | ||
| 279 | char *file = NULL; | ||
| 280 | unsigned int line = 0; | ||
| 281 | struct inline_node *node; | ||
| 282 | |||
| 283 | node = zalloc(sizeof(*node)); | ||
| 284 | if (node == NULL) { | ||
| 285 | perror("not enough memory for the inline node"); | ||
| 286 | return NULL; | ||
| 287 | } | ||
| 288 | |||
| 289 | INIT_LIST_HEAD(&node->val); | ||
| 290 | node->addr = addr; | ||
| 291 | |||
| 292 | if (!addr2line(dso_name, addr, &file, &line, dso, TRUE, node)) | ||
| 293 | goto out_free_inline_node; | ||
| 294 | |||
| 295 | if (list_empty(&node->val)) | ||
| 296 | goto out_free_inline_node; | ||
| 297 | |||
| 298 | return node; | ||
| 299 | |||
| 300 | out_free_inline_node: | ||
| 301 | inline_node__delete(node); | ||
| 302 | return NULL; | ||
| 303 | } | ||
| 304 | |||
| 208 | #else /* HAVE_LIBBFD_SUPPORT */ | 305 | #else /* HAVE_LIBBFD_SUPPORT */ |
| 209 | 306 | ||
| 307 | static int filename_split(char *filename, unsigned int *line_nr) | ||
| 308 | { | ||
| 309 | char *sep; | ||
| 310 | |||
| 311 | sep = strchr(filename, '\n'); | ||
| 312 | if (sep) | ||
| 313 | *sep = '\0'; | ||
| 314 | |||
| 315 | if (!strcmp(filename, "??:0")) | ||
| 316 | return 0; | ||
| 317 | |||
| 318 | sep = strchr(filename, ':'); | ||
| 319 | if (sep) { | ||
| 320 | *sep++ = '\0'; | ||
| 321 | *line_nr = strtoul(sep, NULL, 0); | ||
| 322 | return 1; | ||
| 323 | } | ||
| 324 | |||
| 325 | return 0; | ||
| 326 | } | ||
| 327 | |||
| 210 | static int addr2line(const char *dso_name, u64 addr, | 328 | static int addr2line(const char *dso_name, u64 addr, |
| 211 | char **file, unsigned int *line_nr, | 329 | char **file, unsigned int *line_nr, |
| 212 | struct dso *dso __maybe_unused, | 330 | struct dso *dso __maybe_unused, |
| 213 | bool unwind_inlines __maybe_unused) | 331 | bool unwind_inlines __maybe_unused, |
| 332 | struct inline_node *node __maybe_unused) | ||
| 214 | { | 333 | { |
| 215 | FILE *fp; | 334 | FILE *fp; |
| 216 | char cmd[PATH_MAX]; | 335 | char cmd[PATH_MAX]; |
| 217 | char *filename = NULL; | 336 | char *filename = NULL; |
| 218 | size_t len; | 337 | size_t len; |
| 219 | char *sep; | ||
| 220 | int ret = 0; | 338 | int ret = 0; |
| 221 | 339 | ||
| 222 | scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64, | 340 | scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64, |
| @@ -233,23 +351,14 @@ static int addr2line(const char *dso_name, u64 addr, | |||
| 233 | goto out; | 351 | goto out; |
| 234 | } | 352 | } |
| 235 | 353 | ||
| 236 | sep = strchr(filename, '\n'); | 354 | ret = filename_split(filename, line_nr); |
| 237 | if (sep) | 355 | if (ret != 1) { |
| 238 | *sep = '\0'; | ||
| 239 | |||
| 240 | if (!strcmp(filename, "??:0")) { | ||
| 241 | pr_debug("no debugging info in %s\n", dso_name); | ||
| 242 | free(filename); | 356 | free(filename); |
| 243 | goto out; | 357 | goto out; |
| 244 | } | 358 | } |
| 245 | 359 | ||
| 246 | sep = strchr(filename, ':'); | 360 | *file = filename; |
| 247 | if (sep) { | 361 | |
| 248 | *sep++ = '\0'; | ||
| 249 | *file = filename; | ||
| 250 | *line_nr = strtoul(sep, NULL, 0); | ||
| 251 | ret = 1; | ||
| 252 | } | ||
| 253 | out: | 362 | out: |
| 254 | pclose(fp); | 363 | pclose(fp); |
| 255 | return ret; | 364 | return ret; |
| @@ -259,6 +368,58 @@ void dso__free_a2l(struct dso *dso __maybe_unused) | |||
| 259 | { | 368 | { |
| 260 | } | 369 | } |
| 261 | 370 | ||
| 371 | static struct inline_node *addr2inlines(const char *dso_name, u64 addr, | ||
| 372 | struct dso *dso __maybe_unused) | ||
| 373 | { | ||
| 374 | FILE *fp; | ||
| 375 | char cmd[PATH_MAX]; | ||
| 376 | struct inline_node *node; | ||
| 377 | char *filename = NULL; | ||
| 378 | size_t len; | ||
| 379 | unsigned int line_nr = 0; | ||
| 380 | |||
| 381 | scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i %016"PRIx64, | ||
| 382 | dso_name, addr); | ||
| 383 | |||
| 384 | fp = popen(cmd, "r"); | ||
| 385 | if (fp == NULL) { | ||
| 386 | pr_err("popen failed for %s\n", dso_name); | ||
| 387 | return NULL; | ||
| 388 | } | ||
| 389 | |||
| 390 | node = zalloc(sizeof(*node)); | ||
| 391 | if (node == NULL) { | ||
| 392 | perror("not enough memory for the inline node"); | ||
| 393 | goto out; | ||
| 394 | } | ||
| 395 | |||
| 396 | INIT_LIST_HEAD(&node->val); | ||
| 397 | node->addr = addr; | ||
| 398 | |||
| 399 | while (getline(&filename, &len, fp) != -1) { | ||
| 400 | if (filename_split(filename, &line_nr) != 1) { | ||
| 401 | free(filename); | ||
| 402 | goto out; | ||
| 403 | } | ||
| 404 | |||
| 405 | if (inline_list__append(filename, NULL, line_nr, node, | ||
| 406 | NULL) != 0) | ||
| 407 | goto out; | ||
| 408 | |||
| 409 | filename = NULL; | ||
| 410 | } | ||
| 411 | |||
| 412 | out: | ||
| 413 | pclose(fp); | ||
| 414 | |||
| 415 | if (list_empty(&node->val)) { | ||
| 416 | inline_node__delete(node); | ||
| 417 | return NULL; | ||
| 418 | } | ||
| 419 | |||
| 420 | return node; | ||
| 421 | } | ||
| 422 | |||
| 262 | #endif /* HAVE_LIBBFD_SUPPORT */ | 423 | #endif /* HAVE_LIBBFD_SUPPORT */ |
| 263 | 424 | ||
| 264 | /* | 425 | /* |
| @@ -268,7 +429,7 @@ void dso__free_a2l(struct dso *dso __maybe_unused) | |||
| 268 | #define A2L_FAIL_LIMIT 123 | 429 | #define A2L_FAIL_LIMIT 123 |
| 269 | 430 | ||
| 270 | char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, | 431 | char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, |
| 271 | bool show_sym, bool unwind_inlines) | 432 | bool show_sym, bool show_addr, bool unwind_inlines) |
| 272 | { | 433 | { |
| 273 | char *file = NULL; | 434 | char *file = NULL; |
| 274 | unsigned line = 0; | 435 | unsigned line = 0; |
| @@ -278,18 +439,11 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, | |||
| 278 | if (!dso->has_srcline) | 439 | if (!dso->has_srcline) |
| 279 | goto out; | 440 | goto out; |
| 280 | 441 | ||
| 281 | if (dso->symsrc_filename) | 442 | dso_name = dso__name(dso); |
| 282 | dso_name = dso->symsrc_filename; | 443 | if (dso_name == NULL) |
| 283 | else | ||
| 284 | dso_name = dso->long_name; | ||
| 285 | |||
| 286 | if (dso_name[0] == '[') | ||
| 287 | goto out; | ||
| 288 | |||
| 289 | if (!strncmp(dso_name, "/tmp/perf-", 10)) | ||
| 290 | goto out; | 444 | goto out; |
| 291 | 445 | ||
| 292 | if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines)) | 446 | if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines, NULL)) |
| 293 | goto out; | 447 | goto out; |
| 294 | 448 | ||
| 295 | if (asprintf(&srcline, "%s:%u", | 449 | if (asprintf(&srcline, "%s:%u", |
| @@ -309,6 +463,11 @@ out: | |||
| 309 | dso->has_srcline = 0; | 463 | dso->has_srcline = 0; |
| 310 | dso__free_a2l(dso); | 464 | dso__free_a2l(dso); |
| 311 | } | 465 | } |
| 466 | |||
| 467 | if (!show_addr) | ||
| 468 | return (show_sym && sym) ? | ||
| 469 | strndup(sym->name, sym->namelen) : NULL; | ||
| 470 | |||
| 312 | if (sym) { | 471 | if (sym) { |
| 313 | if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", | 472 | if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", |
| 314 | addr - sym->start) < 0) | 473 | addr - sym->start) < 0) |
| @@ -325,7 +484,32 @@ void free_srcline(char *srcline) | |||
| 325 | } | 484 | } |
| 326 | 485 | ||
| 327 | char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, | 486 | char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, |
| 328 | bool show_sym) | 487 | bool show_sym, bool show_addr) |
| 488 | { | ||
| 489 | return __get_srcline(dso, addr, sym, show_sym, show_addr, false); | ||
| 490 | } | ||
| 491 | |||
| 492 | struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr) | ||
| 329 | { | 493 | { |
| 330 | return __get_srcline(dso, addr, sym, show_sym, false); | 494 | const char *dso_name; |
| 495 | |||
| 496 | dso_name = dso__name(dso); | ||
| 497 | if (dso_name == NULL) | ||
| 498 | return NULL; | ||
| 499 | |||
| 500 | return addr2inlines(dso_name, addr, dso); | ||
| 501 | } | ||
| 502 | |||
| 503 | void inline_node__delete(struct inline_node *node) | ||
| 504 | { | ||
| 505 | struct inline_list *ilist, *tmp; | ||
| 506 | |||
| 507 | list_for_each_entry_safe(ilist, tmp, &node->val, list) { | ||
| 508 | list_del_init(&ilist->list); | ||
| 509 | zfree(&ilist->filename); | ||
| 510 | zfree(&ilist->funcname); | ||
| 511 | free(ilist); | ||
| 512 | } | ||
| 513 | |||
| 514 | free(node); | ||
| 331 | } | 515 | } |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 0e660dba58ad..d1a40bb642ff 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
| @@ -390,6 +390,11 @@ out_elf_end: | |||
| 390 | return 0; | 390 | return 0; |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name) | ||
| 394 | { | ||
| 395 | return demangle_sym(dso, kmodule, elf_name); | ||
| 396 | } | ||
| 397 | |||
| 393 | /* | 398 | /* |
| 394 | * Align offset to 4 bytes as needed for note name and descriptor data. | 399 | * Align offset to 4 bytes as needed for note name and descriptor data. |
| 395 | */ | 400 | */ |
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 11cdde980545..870ef0f0659c 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c | |||
| @@ -373,3 +373,10 @@ int kcore_copy(const char *from_dir __maybe_unused, | |||
| 373 | void symbol__elf_init(void) | 373 | void symbol__elf_init(void) |
| 374 | { | 374 | { |
| 375 | } | 375 | } |
| 376 | |||
| 377 | char *dso__demangle_sym(struct dso *dso __maybe_unused, | ||
| 378 | int kmodule __maybe_unused, | ||
| 379 | char *elf_name __maybe_unused) | ||
| 380 | { | ||
| 381 | return NULL; | ||
| 382 | } | ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 9222c7e702f3..5245d2fb1a0a 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -118,7 +118,8 @@ struct symbol_conf { | |||
| 118 | show_ref_callgraph, | 118 | show_ref_callgraph, |
| 119 | hide_unresolved, | 119 | hide_unresolved, |
| 120 | raw_trace, | 120 | raw_trace, |
| 121 | report_hierarchy; | 121 | report_hierarchy, |
| 122 | inline_name; | ||
| 122 | const char *vmlinux_name, | 123 | const char *vmlinux_name, |
| 123 | *kallsyms_name, | 124 | *kallsyms_name, |
| 124 | *source_prefix, | 125 | *source_prefix, |
| @@ -305,6 +306,8 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, | |||
| 305 | int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, | 306 | int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, |
| 306 | struct map *map); | 307 | struct map *map); |
| 307 | 308 | ||
| 309 | char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name); | ||
| 310 | |||
| 308 | void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel); | 311 | void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel); |
| 309 | void symbols__insert(struct rb_root *symbols, struct symbol *sym); | 312 | void symbols__insert(struct rb_root *symbols, struct symbol *sym); |
| 310 | void symbols__fixup_duplicate(struct rb_root *symbols); | 313 | void symbols__fixup_duplicate(struct rb_root *symbols); |
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index 27420159bf69..8a9a677f7576 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c | |||
| @@ -192,7 +192,7 @@ static int read_ftrace_printk(struct pevent *pevent) | |||
| 192 | if (!size) | 192 | if (!size) |
| 193 | return 0; | 193 | return 0; |
| 194 | 194 | ||
| 195 | buf = malloc(size); | 195 | buf = malloc(size + 1); |
| 196 | if (buf == NULL) | 196 | if (buf == NULL) |
| 197 | return -1; | 197 | return -1; |
| 198 | 198 | ||
| @@ -201,6 +201,8 @@ static int read_ftrace_printk(struct pevent *pevent) | |||
| 201 | return -1; | 201 | return -1; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | buf[size] = '\0'; | ||
| 205 | |||
| 204 | parse_ftrace_printk(pevent, buf, size); | 206 | parse_ftrace_printk(pevent, buf, size); |
| 205 | 207 | ||
| 206 | free(buf); | 208 | free(buf); |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index b2cfa47990dc..7cf5752b38fd 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
| @@ -287,9 +287,9 @@ struct symbol; | |||
| 287 | 287 | ||
| 288 | extern bool srcline_full_filename; | 288 | extern bool srcline_full_filename; |
| 289 | char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, | 289 | char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, |
| 290 | bool show_sym); | 290 | bool show_sym, bool show_addr); |
| 291 | char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, | 291 | char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, |
| 292 | bool show_sym, bool unwind_inlines); | 292 | bool show_sym, bool show_addr, bool unwind_inlines); |
| 293 | void free_srcline(char *srcline); | 293 | void free_srcline(char *srcline); |
| 294 | 294 | ||
| 295 | int perf_event_paranoid(void); | 295 | int perf_event_paranoid(void); |
| @@ -364,4 +364,20 @@ int is_printable_array(char *p, unsigned int len); | |||
| 364 | int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz); | 364 | int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz); |
| 365 | 365 | ||
| 366 | int unit_number__scnprintf(char *buf, size_t size, u64 n); | 366 | int unit_number__scnprintf(char *buf, size_t size, u64 n); |
| 367 | |||
| 368 | struct inline_list { | ||
| 369 | char *filename; | ||
| 370 | char *funcname; | ||
| 371 | unsigned int line_nr; | ||
| 372 | struct list_head list; | ||
| 373 | }; | ||
| 374 | |||
| 375 | struct inline_node { | ||
| 376 | u64 addr; | ||
| 377 | struct list_head val; | ||
| 378 | }; | ||
| 379 | |||
| 380 | struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr); | ||
| 381 | void inline_node__delete(struct inline_node *node); | ||
| 382 | |||
| 367 | #endif /* GIT_COMPAT_UTIL_H */ | 383 | #endif /* GIT_COMPAT_UTIL_H */ |
