diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-07-18 06:19:57 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-07-18 06:20:01 -0400 |
| commit | 45bceffc3013bda7d2ebc7802e9b153b674e2d44 (patch) | |
| tree | 222d7dd8fd300925cbf12cdc0fba5bee2528997e /tools/perf/builtin-annotate.c | |
| parent | 6f2f3cf00ee32f75ba007a46bab88a54d68a5deb (diff) | |
| parent | 78af08d90b8f745044b1274430bc4bc6b2b27aca (diff) | |
Merge branch 'linus' into tracing/core
Merge reason: tracing/core was on an older, pre-rc1 base.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-annotate.c')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 77 |
1 files changed, 35 insertions, 42 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 7e58e3ad1508..5f9eefecc574 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -10,9 +10,9 @@ | |||
| 10 | #include "util/util.h" | 10 | #include "util/util.h" |
| 11 | 11 | ||
| 12 | #include "util/color.h" | 12 | #include "util/color.h" |
| 13 | #include "util/list.h" | 13 | #include <linux/list.h> |
| 14 | #include "util/cache.h" | 14 | #include "util/cache.h" |
| 15 | #include "util/rbtree.h" | 15 | #include <linux/rbtree.h> |
| 16 | #include "util/symbol.h" | 16 | #include "util/symbol.h" |
| 17 | #include "util/string.h" | 17 | #include "util/string.h" |
| 18 | 18 | ||
| @@ -25,10 +25,6 @@ | |||
| 25 | #define SHOW_USER 2 | 25 | #define SHOW_USER 2 |
| 26 | #define SHOW_HV 4 | 26 | #define SHOW_HV 4 |
| 27 | 27 | ||
| 28 | #define MIN_GREEN 0.5 | ||
| 29 | #define MIN_RED 5.0 | ||
| 30 | |||
| 31 | |||
| 32 | static char const *input_name = "perf.data"; | 28 | static char const *input_name = "perf.data"; |
| 33 | static char *vmlinux = "vmlinux"; | 29 | static char *vmlinux = "vmlinux"; |
| 34 | 30 | ||
| @@ -43,6 +39,10 @@ static int dump_trace = 0; | |||
| 43 | 39 | ||
| 44 | static int verbose; | 40 | static int verbose; |
| 45 | 41 | ||
| 42 | static int modules; | ||
| 43 | |||
| 44 | static int full_paths; | ||
| 45 | |||
| 46 | static int print_line; | 46 | static int print_line; |
| 47 | 47 | ||
| 48 | static unsigned long page_size; | 48 | static unsigned long page_size; |
| @@ -160,7 +160,7 @@ static void dsos__fprintf(FILE *fp) | |||
| 160 | 160 | ||
| 161 | static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) | 161 | static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) |
| 162 | { | 162 | { |
| 163 | return dso__find_symbol(kernel_dso, ip); | 163 | return dso__find_symbol(dso, ip); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | static int load_kernel(void) | 166 | static int load_kernel(void) |
| @@ -171,8 +171,8 @@ static int load_kernel(void) | |||
| 171 | if (!kernel_dso) | 171 | if (!kernel_dso) |
| 172 | return -1; | 172 | return -1; |
| 173 | 173 | ||
| 174 | err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose); | 174 | err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules); |
| 175 | if (err) { | 175 | if (err <= 0) { |
| 176 | dso__delete(kernel_dso); | 176 | dso__delete(kernel_dso); |
| 177 | kernel_dso = NULL; | 177 | kernel_dso = NULL; |
| 178 | } else | 178 | } else |
| @@ -203,7 +203,7 @@ static u64 map__map_ip(struct map *map, u64 ip) | |||
| 203 | return ip - map->start + map->pgoff; | 203 | return ip - map->start + map->pgoff; |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | static u64 vdso__map_ip(struct map *map, u64 ip) | 206 | static u64 vdso__map_ip(struct map *map __used, u64 ip) |
| 207 | { | 207 | { |
| 208 | return ip; | 208 | return ip; |
| 209 | } | 209 | } |
| @@ -600,7 +600,7 @@ static LIST_HEAD(hist_entry__sort_list); | |||
| 600 | 600 | ||
| 601 | static int sort_dimension__add(char *tok) | 601 | static int sort_dimension__add(char *tok) |
| 602 | { | 602 | { |
| 603 | int i; | 603 | unsigned int i; |
| 604 | 604 | ||
| 605 | for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { | 605 | for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { |
| 606 | struct sort_dimension *sd = &sort_dimensions[i]; | 606 | struct sort_dimension *sd = &sort_dimensions[i]; |
| @@ -855,7 +855,7 @@ static unsigned long total = 0, | |||
| 855 | total_unknown = 0; | 855 | total_unknown = 0; |
| 856 | 856 | ||
| 857 | static int | 857 | static int |
| 858 | process_overflow_event(event_t *event, unsigned long offset, unsigned long head) | 858 | process_sample_event(event_t *event, unsigned long offset, unsigned long head) |
| 859 | { | 859 | { |
| 860 | char level; | 860 | char level; |
| 861 | int show = 0; | 861 | int show = 0; |
| @@ -1013,10 +1013,10 @@ process_period_event(event_t *event, unsigned long offset, unsigned long head) | |||
| 1013 | static int | 1013 | static int |
| 1014 | process_event(event_t *event, unsigned long offset, unsigned long head) | 1014 | process_event(event_t *event, unsigned long offset, unsigned long head) |
| 1015 | { | 1015 | { |
| 1016 | if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) | ||
| 1017 | return process_overflow_event(event, offset, head); | ||
| 1018 | |||
| 1019 | switch (event->header.type) { | 1016 | switch (event->header.type) { |
| 1017 | case PERF_EVENT_SAMPLE: | ||
| 1018 | return process_sample_event(event, offset, head); | ||
| 1019 | |||
| 1020 | case PERF_EVENT_MMAP: | 1020 | case PERF_EVENT_MMAP: |
| 1021 | return process_mmap_event(event, offset, head); | 1021 | return process_mmap_event(event, offset, head); |
| 1022 | 1022 | ||
| @@ -1043,24 +1043,6 @@ process_event(event_t *event, unsigned long offset, unsigned long head) | |||
| 1043 | return 0; | 1043 | return 0; |
| 1044 | } | 1044 | } |
| 1045 | 1045 | ||
| 1046 | static char *get_color(double percent) | ||
| 1047 | { | ||
| 1048 | char *color = PERF_COLOR_NORMAL; | ||
| 1049 | |||
| 1050 | /* | ||
| 1051 | * We color high-overhead entries in red, mid-overhead | ||
| 1052 | * entries in green - and keep the low overhead places | ||
| 1053 | * normal: | ||
| 1054 | */ | ||
| 1055 | if (percent >= MIN_RED) | ||
| 1056 | color = PERF_COLOR_RED; | ||
| 1057 | else { | ||
| 1058 | if (percent > MIN_GREEN) | ||
| 1059 | color = PERF_COLOR_GREEN; | ||
| 1060 | } | ||
| 1061 | return color; | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | static int | 1046 | static int |
| 1065 | parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) | 1047 | parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) |
| 1066 | { | 1048 | { |
| @@ -1069,7 +1051,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) | |||
| 1069 | static const char *prev_color; | 1051 | static const char *prev_color; |
| 1070 | unsigned int offset; | 1052 | unsigned int offset; |
| 1071 | size_t line_len; | 1053 | size_t line_len; |
| 1072 | u64 line_ip; | 1054 | s64 line_ip; |
| 1073 | int ret; | 1055 | int ret; |
| 1074 | char *c; | 1056 | char *c; |
| 1075 | 1057 | ||
| @@ -1122,7 +1104,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) | |||
| 1122 | } else if (sym->hist_sum) | 1104 | } else if (sym->hist_sum) |
| 1123 | percent = 100.0 * hits / sym->hist_sum; | 1105 | percent = 100.0 * hits / sym->hist_sum; |
| 1124 | 1106 | ||
| 1125 | color = get_color(percent); | 1107 | color = get_percent_color(percent); |
| 1126 | 1108 | ||
| 1127 | /* | 1109 | /* |
| 1128 | * Also color the filename and line if needed, with | 1110 | * Also color the filename and line if needed, with |
| @@ -1258,7 +1240,7 @@ static void print_summary(char *filename) | |||
| 1258 | 1240 | ||
| 1259 | sym_ext = rb_entry(node, struct sym_ext, node); | 1241 | sym_ext = rb_entry(node, struct sym_ext, node); |
| 1260 | percent = sym_ext->percent; | 1242 | percent = sym_ext->percent; |
| 1261 | color = get_color(percent); | 1243 | color = get_percent_color(percent); |
| 1262 | path = sym_ext->path; | 1244 | path = sym_ext->path; |
| 1263 | 1245 | ||
| 1264 | color_fprintf(stdout, color, " %7.2f %s", percent, path); | 1246 | color_fprintf(stdout, color, " %7.2f %s", percent, path); |
| @@ -1268,19 +1250,25 @@ static void print_summary(char *filename) | |||
| 1268 | 1250 | ||
| 1269 | static void annotate_sym(struct dso *dso, struct symbol *sym) | 1251 | static void annotate_sym(struct dso *dso, struct symbol *sym) |
| 1270 | { | 1252 | { |
| 1271 | char *filename = dso->name; | 1253 | char *filename = dso->name, *d_filename; |
| 1272 | u64 start, end, len; | 1254 | u64 start, end, len; |
| 1273 | char command[PATH_MAX*2]; | 1255 | char command[PATH_MAX*2]; |
| 1274 | FILE *file; | 1256 | FILE *file; |
| 1275 | 1257 | ||
| 1276 | if (!filename) | 1258 | if (!filename) |
| 1277 | return; | 1259 | return; |
| 1278 | if (dso == kernel_dso) | 1260 | if (sym->module) |
| 1261 | filename = sym->module->path; | ||
| 1262 | else if (dso == kernel_dso) | ||
| 1279 | filename = vmlinux; | 1263 | filename = vmlinux; |
| 1280 | 1264 | ||
| 1281 | start = sym->obj_start; | 1265 | start = sym->obj_start; |
| 1282 | if (!start) | 1266 | if (!start) |
| 1283 | start = sym->start; | 1267 | start = sym->start; |
| 1268 | if (full_paths) | ||
| 1269 | d_filename = filename; | ||
| 1270 | else | ||
| 1271 | d_filename = basename(filename); | ||
| 1284 | 1272 | ||
| 1285 | end = start + sym->end - sym->start + 1; | 1273 | end = start + sym->end - sym->start + 1; |
| 1286 | len = sym->end - sym->start; | 1274 | len = sym->end - sym->start; |
| @@ -1291,13 +1279,14 @@ static void annotate_sym(struct dso *dso, struct symbol *sym) | |||
| 1291 | } | 1279 | } |
| 1292 | 1280 | ||
| 1293 | printf("\n\n------------------------------------------------\n"); | 1281 | printf("\n\n------------------------------------------------\n"); |
| 1294 | printf(" Percent | Source code & Disassembly of %s\n", filename); | 1282 | printf(" Percent | Source code & Disassembly of %s\n", d_filename); |
| 1295 | printf("------------------------------------------------\n"); | 1283 | printf("------------------------------------------------\n"); |
| 1296 | 1284 | ||
| 1297 | if (verbose >= 2) | 1285 | if (verbose >= 2) |
| 1298 | printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name); | 1286 | printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name); |
| 1299 | 1287 | ||
| 1300 | sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (u64)start, (u64)end, filename); | 1288 | sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s", |
| 1289 | (u64)start, (u64)end, filename, filename); | ||
| 1301 | 1290 | ||
| 1302 | if (verbose >= 3) | 1291 | if (verbose >= 3) |
| 1303 | printf("doing: %s\n", command); | 1292 | printf("doing: %s\n", command); |
| @@ -1428,7 +1417,7 @@ more: | |||
| 1428 | 1417 | ||
| 1429 | head += size; | 1418 | head += size; |
| 1430 | 1419 | ||
| 1431 | if (offset + head < stat.st_size) | 1420 | if (offset + head < (unsigned long)stat.st_size) |
| 1432 | goto more; | 1421 | goto more; |
| 1433 | 1422 | ||
| 1434 | rc = EXIT_SUCCESS; | 1423 | rc = EXIT_SUCCESS; |
| @@ -1472,8 +1461,12 @@ static const struct option options[] = { | |||
| 1472 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, | 1461 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, |
| 1473 | "dump raw trace in ASCII"), | 1462 | "dump raw trace in ASCII"), |
| 1474 | OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), | 1463 | OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), |
| 1464 | OPT_BOOLEAN('m', "modules", &modules, | ||
| 1465 | "load module symbols - WARNING: use only with -k and LIVE kernel"), | ||
| 1475 | OPT_BOOLEAN('l', "print-line", &print_line, | 1466 | OPT_BOOLEAN('l', "print-line", &print_line, |
| 1476 | "print matching source lines (may be slow)"), | 1467 | "print matching source lines (may be slow)"), |
| 1468 | OPT_BOOLEAN('P', "full-paths", &full_paths, | ||
| 1469 | "Don't shorten the displayed pathnames"), | ||
| 1477 | OPT_END() | 1470 | OPT_END() |
| 1478 | }; | 1471 | }; |
| 1479 | 1472 | ||
| @@ -1492,7 +1485,7 @@ static void setup_sorting(void) | |||
| 1492 | free(str); | 1485 | free(str); |
| 1493 | } | 1486 | } |
| 1494 | 1487 | ||
| 1495 | int cmd_annotate(int argc, const char **argv, const char *prefix) | 1488 | int cmd_annotate(int argc, const char **argv, const char *prefix __used) |
| 1496 | { | 1489 | { |
| 1497 | symbol__init(); | 1490 | symbol__init(); |
| 1498 | 1491 | ||
