diff options
| -rw-r--r-- | tools/perf/util/intel-pt.c | 9 | ||||
| -rw-r--r-- | tools/perf/util/parse-events.c | 3 | ||||
| -rw-r--r-- | tools/perf/util/probe-finder.c | 62 | ||||
| -rw-r--r-- | tools/perf/util/probe-finder.h | 5 |
4 files changed, 53 insertions, 26 deletions
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 81a2eb77ba7f..05d815851be1 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c | |||
| @@ -2068,6 +2068,15 @@ int intel_pt_process_auxtrace_info(union perf_event *event, | |||
| 2068 | err = -ENOMEM; | 2068 | err = -ENOMEM; |
| 2069 | goto err_free_queues; | 2069 | goto err_free_queues; |
| 2070 | } | 2070 | } |
| 2071 | |||
| 2072 | /* | ||
| 2073 | * Since this thread will not be kept in any rbtree not in a | ||
| 2074 | * list, initialize its list node so that at thread__put() the | ||
| 2075 | * current thread lifetime assuption is kept and we don't segfault | ||
| 2076 | * at list_del_init(). | ||
| 2077 | */ | ||
| 2078 | INIT_LIST_HEAD(&pt->unknown_thread->node); | ||
| 2079 | |||
| 2071 | err = thread__set_comm(pt->unknown_thread, "unknown", 0); | 2080 | err = thread__set_comm(pt->unknown_thread, "unknown", 0); |
| 2072 | if (err) | 2081 | if (err) |
| 2073 | goto err_delete_thread; | 2082 | goto err_delete_thread; |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 4f7b0efdde2f..813d9b272c81 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
| @@ -399,6 +399,9 @@ static void tracepoint_error(struct parse_events_error *e, int err, | |||
| 399 | { | 399 | { |
| 400 | char help[BUFSIZ]; | 400 | char help[BUFSIZ]; |
| 401 | 401 | ||
| 402 | if (!e) | ||
| 403 | return; | ||
| 404 | |||
| 402 | /* | 405 | /* |
| 403 | * We get error directly from syscall errno ( > 0), | 406 | * We get error directly from syscall errno ( > 0), |
| 404 | * or from encoded pointer's error ( < 0). | 407 | * or from encoded pointer's error ( < 0). |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 2be10fb27172..4ce5c5e18f48 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
| @@ -686,8 +686,9 @@ static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
| 686 | pf->fb_ops = NULL; | 686 | pf->fb_ops = NULL; |
| 687 | #if _ELFUTILS_PREREQ(0, 142) | 687 | #if _ELFUTILS_PREREQ(0, 142) |
| 688 | } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa && | 688 | } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa && |
| 689 | pf->cfi != NULL) { | 689 | (pf->cfi_eh != NULL || pf->cfi_dbg != NULL)) { |
| 690 | if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 || | 690 | if ((dwarf_cfi_addrframe(pf->cfi_eh, pf->addr, &frame) != 0 && |
| 691 | (dwarf_cfi_addrframe(pf->cfi_dbg, pf->addr, &frame) != 0)) || | ||
| 691 | dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) { | 692 | dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) { |
| 692 | pr_warning("Failed to get call frame on 0x%jx\n", | 693 | pr_warning("Failed to get call frame on 0x%jx\n", |
| 693 | (uintmax_t)pf->addr); | 694 | (uintmax_t)pf->addr); |
| @@ -1015,8 +1016,7 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data) | |||
| 1015 | return DWARF_CB_OK; | 1016 | return DWARF_CB_OK; |
| 1016 | } | 1017 | } |
| 1017 | 1018 | ||
| 1018 | /* Find probe points from debuginfo */ | 1019 | static int debuginfo__find_probe_location(struct debuginfo *dbg, |
| 1019 | static int debuginfo__find_probes(struct debuginfo *dbg, | ||
| 1020 | struct probe_finder *pf) | 1020 | struct probe_finder *pf) |
| 1021 | { | 1021 | { |
| 1022 | struct perf_probe_point *pp = &pf->pev->point; | 1022 | struct perf_probe_point *pp = &pf->pev->point; |
| @@ -1025,27 +1025,6 @@ static int debuginfo__find_probes(struct debuginfo *dbg, | |||
| 1025 | Dwarf_Die *diep; | 1025 | Dwarf_Die *diep; |
| 1026 | int ret = 0; | 1026 | int ret = 0; |
| 1027 | 1027 | ||
| 1028 | #if _ELFUTILS_PREREQ(0, 142) | ||
| 1029 | Elf *elf; | ||
| 1030 | GElf_Ehdr ehdr; | ||
| 1031 | GElf_Shdr shdr; | ||
| 1032 | |||
| 1033 | /* Get the call frame information from this dwarf */ | ||
| 1034 | elf = dwarf_getelf(dbg->dbg); | ||
| 1035 | if (elf == NULL) | ||
| 1036 | return -EINVAL; | ||
| 1037 | |||
| 1038 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
| 1039 | return -EINVAL; | ||
| 1040 | |||
| 1041 | if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) && | ||
| 1042 | shdr.sh_type == SHT_PROGBITS) { | ||
| 1043 | pf->cfi = dwarf_getcfi_elf(elf); | ||
| 1044 | } else { | ||
| 1045 | pf->cfi = dwarf_getcfi(dbg->dbg); | ||
| 1046 | } | ||
| 1047 | #endif | ||
| 1048 | |||
| 1049 | off = 0; | 1028 | off = 0; |
| 1050 | pf->lcache = intlist__new(NULL); | 1029 | pf->lcache = intlist__new(NULL); |
| 1051 | if (!pf->lcache) | 1030 | if (!pf->lcache) |
| @@ -1108,6 +1087,39 @@ found: | |||
| 1108 | return ret; | 1087 | return ret; |
| 1109 | } | 1088 | } |
| 1110 | 1089 | ||
| 1090 | /* Find probe points from debuginfo */ | ||
| 1091 | static int debuginfo__find_probes(struct debuginfo *dbg, | ||
| 1092 | struct probe_finder *pf) | ||
| 1093 | { | ||
| 1094 | int ret = 0; | ||
| 1095 | |||
| 1096 | #if _ELFUTILS_PREREQ(0, 142) | ||
| 1097 | Elf *elf; | ||
| 1098 | GElf_Ehdr ehdr; | ||
| 1099 | GElf_Shdr shdr; | ||
| 1100 | |||
| 1101 | if (pf->cfi_eh || pf->cfi_dbg) | ||
| 1102 | return debuginfo__find_probe_location(dbg, pf); | ||
| 1103 | |||
| 1104 | /* Get the call frame information from this dwarf */ | ||
| 1105 | elf = dwarf_getelf(dbg->dbg); | ||
| 1106 | if (elf == NULL) | ||
| 1107 | return -EINVAL; | ||
| 1108 | |||
| 1109 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
| 1110 | return -EINVAL; | ||
| 1111 | |||
| 1112 | if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) && | ||
| 1113 | shdr.sh_type == SHT_PROGBITS) | ||
| 1114 | pf->cfi_eh = dwarf_getcfi_elf(elf); | ||
| 1115 | |||
| 1116 | pf->cfi_dbg = dwarf_getcfi(dbg->dbg); | ||
| 1117 | #endif | ||
| 1118 | |||
| 1119 | ret = debuginfo__find_probe_location(dbg, pf); | ||
| 1120 | return ret; | ||
| 1121 | } | ||
| 1122 | |||
| 1111 | struct local_vars_finder { | 1123 | struct local_vars_finder { |
| 1112 | struct probe_finder *pf; | 1124 | struct probe_finder *pf; |
| 1113 | struct perf_probe_arg *args; | 1125 | struct perf_probe_arg *args; |
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index bed82716e1b4..0aec7704e395 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h | |||
| @@ -76,7 +76,10 @@ struct probe_finder { | |||
| 76 | 76 | ||
| 77 | /* For variable searching */ | 77 | /* For variable searching */ |
| 78 | #if _ELFUTILS_PREREQ(0, 142) | 78 | #if _ELFUTILS_PREREQ(0, 142) |
| 79 | Dwarf_CFI *cfi; /* Call Frame Information */ | 79 | /* Call Frame Information from .eh_frame */ |
| 80 | Dwarf_CFI *cfi_eh; | ||
| 81 | /* Call Frame Information from .debug_frame */ | ||
| 82 | Dwarf_CFI *cfi_dbg; | ||
| 80 | #endif | 83 | #endif |
| 81 | Dwarf_Op *fb_ops; /* Frame base attribute */ | 84 | Dwarf_Op *fb_ops; /* Frame base attribute */ |
| 82 | struct perf_probe_arg *pvar; /* Current target variable */ | 85 | struct perf_probe_arg *pvar; /* Current target variable */ |
