diff options
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/callchain.h | 3 | ||||
-rw-r--r-- | tools/perf/util/dwarf-aux.c | 25 | ||||
-rw-r--r-- | tools/perf/util/dwarf-aux.h | 6 | ||||
-rw-r--r-- | tools/perf/util/event.c | 32 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 13 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 2 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 1 | ||||
-rw-r--r-- | tools/perf/util/header.c | 12 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 13 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 49 | ||||
-rw-r--r-- | tools/perf/util/python.c | 2 | ||||
-rw-r--r-- | tools/perf/util/scripting-engines/trace-event-perl.c | 2 | ||||
-rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 37 | ||||
-rw-r--r-- | tools/perf/util/session.c | 4 |
14 files changed, 143 insertions, 58 deletions
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 2b585bc308cf..9e99060408ae 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -147,6 +147,9 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor) | |||
147 | 147 | ||
148 | struct option; | 148 | struct option; |
149 | 149 | ||
150 | int record_parse_callchain(const char *arg, struct perf_record_opts *opts); | ||
150 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); | 151 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); |
152 | int record_callchain_opt(const struct option *opt, const char *arg, int unset); | ||
153 | |||
151 | extern const char record_callchain_help[]; | 154 | extern const char record_callchain_help[]; |
152 | #endif /* __PERF_CALLCHAIN_H */ | 155 | #endif /* __PERF_CALLCHAIN_H */ |
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index e23bde19d590..7defd77105d0 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c | |||
@@ -426,7 +426,7 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) | |||
426 | * @die_mem: a buffer for result DIE | 426 | * @die_mem: a buffer for result DIE |
427 | * | 427 | * |
428 | * Search a non-inlined function DIE which includes @addr. Stores the | 428 | * Search a non-inlined function DIE which includes @addr. Stores the |
429 | * DIE to @die_mem and returns it if found. Returns NULl if failed. | 429 | * DIE to @die_mem and returns it if found. Returns NULL if failed. |
430 | */ | 430 | */ |
431 | Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, | 431 | Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, |
432 | Dwarf_Die *die_mem) | 432 | Dwarf_Die *die_mem) |
@@ -454,15 +454,32 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) | |||
454 | } | 454 | } |
455 | 455 | ||
456 | /** | 456 | /** |
457 | * die_find_top_inlinefunc - Search the top inlined function at given address | ||
458 | * @sp_die: a subprogram DIE which including @addr | ||
459 | * @addr: target address | ||
460 | * @die_mem: a buffer for result DIE | ||
461 | * | ||
462 | * Search an inlined function DIE which includes @addr. Stores the | ||
463 | * DIE to @die_mem and returns it if found. Returns NULL if failed. | ||
464 | * Even if several inlined functions are expanded recursively, this | ||
465 | * doesn't trace it down, and returns the topmost one. | ||
466 | */ | ||
467 | Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | ||
468 | Dwarf_Die *die_mem) | ||
469 | { | ||
470 | return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); | ||
471 | } | ||
472 | |||
473 | /** | ||
457 | * die_find_inlinefunc - Search an inlined function at given address | 474 | * die_find_inlinefunc - Search an inlined function at given address |
458 | * @cu_die: a CU DIE which including @addr | 475 | * @sp_die: a subprogram DIE which including @addr |
459 | * @addr: target address | 476 | * @addr: target address |
460 | * @die_mem: a buffer for result DIE | 477 | * @die_mem: a buffer for result DIE |
461 | * | 478 | * |
462 | * Search an inlined function DIE which includes @addr. Stores the | 479 | * Search an inlined function DIE which includes @addr. Stores the |
463 | * DIE to @die_mem and returns it if found. Returns NULl if failed. | 480 | * DIE to @die_mem and returns it if found. Returns NULL if failed. |
464 | * If several inlined functions are expanded recursively, this trace | 481 | * If several inlined functions are expanded recursively, this trace |
465 | * it and returns deepest one. | 482 | * it down and returns deepest one. |
466 | */ | 483 | */ |
467 | Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | 484 | Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, |
468 | Dwarf_Die *die_mem) | 485 | Dwarf_Die *die_mem) |
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 8658d41697d2..b4fe90c6cb2d 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h | |||
@@ -79,7 +79,11 @@ extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die, | |||
79 | extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, | 79 | extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, |
80 | Dwarf_Die *die_mem); | 80 | Dwarf_Die *die_mem); |
81 | 81 | ||
82 | /* Search an inlined function including given address */ | 82 | /* Search the top inlined function including given address */ |
83 | extern Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | ||
84 | Dwarf_Die *die_mem); | ||
85 | |||
86 | /* Search the deepest inlined function including given address */ | ||
83 | extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | 87 | extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, |
84 | Dwarf_Die *die_mem); | 88 | Dwarf_Die *die_mem); |
85 | 89 | ||
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 9b393e7dca6f..49096ea58a15 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -187,7 +187,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
187 | return -1; | 187 | return -1; |
188 | } | 188 | } |
189 | 189 | ||
190 | event->header.type = PERF_RECORD_MMAP2; | 190 | event->header.type = PERF_RECORD_MMAP; |
191 | /* | 191 | /* |
192 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c | 192 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c |
193 | */ | 193 | */ |
@@ -198,7 +198,6 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
198 | char prot[5]; | 198 | char prot[5]; |
199 | char execname[PATH_MAX]; | 199 | char execname[PATH_MAX]; |
200 | char anonstr[] = "//anon"; | 200 | char anonstr[] = "//anon"; |
201 | unsigned int ino; | ||
202 | size_t size; | 201 | size_t size; |
203 | ssize_t n; | 202 | ssize_t n; |
204 | 203 | ||
@@ -209,15 +208,12 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
209 | strcpy(execname, ""); | 208 | strcpy(execname, ""); |
210 | 209 | ||
211 | /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ | 210 | /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ |
212 | n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n", | 211 | n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n", |
213 | &event->mmap2.start, &event->mmap2.len, prot, | 212 | &event->mmap.start, &event->mmap.len, prot, |
214 | &event->mmap2.pgoff, &event->mmap2.maj, | 213 | &event->mmap.pgoff, |
215 | &event->mmap2.min, | 214 | execname); |
216 | &ino, execname); | ||
217 | |||
218 | event->mmap2.ino = (u64)ino; | ||
219 | 215 | ||
220 | if (n != 8) | 216 | if (n != 5) |
221 | continue; | 217 | continue; |
222 | 218 | ||
223 | if (prot[2] != 'x') | 219 | if (prot[2] != 'x') |
@@ -227,15 +223,15 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
227 | strcpy(execname, anonstr); | 223 | strcpy(execname, anonstr); |
228 | 224 | ||
229 | size = strlen(execname) + 1; | 225 | size = strlen(execname) + 1; |
230 | memcpy(event->mmap2.filename, execname, size); | 226 | memcpy(event->mmap.filename, execname, size); |
231 | size = PERF_ALIGN(size, sizeof(u64)); | 227 | size = PERF_ALIGN(size, sizeof(u64)); |
232 | event->mmap2.len -= event->mmap.start; | 228 | event->mmap.len -= event->mmap.start; |
233 | event->mmap2.header.size = (sizeof(event->mmap2) - | 229 | event->mmap.header.size = (sizeof(event->mmap) - |
234 | (sizeof(event->mmap2.filename) - size)); | 230 | (sizeof(event->mmap.filename) - size)); |
235 | memset(event->mmap2.filename + size, 0, machine->id_hdr_size); | 231 | memset(event->mmap.filename + size, 0, machine->id_hdr_size); |
236 | event->mmap2.header.size += machine->id_hdr_size; | 232 | event->mmap.header.size += machine->id_hdr_size; |
237 | event->mmap2.pid = tgid; | 233 | event->mmap.pid = tgid; |
238 | event->mmap2.tid = pid; | 234 | event->mmap.tid = pid; |
239 | 235 | ||
240 | if (process(tool, event, &synth_sample, machine) != 0) { | 236 | if (process(tool, event, &synth_sample, machine) != 0) { |
241 | rc = -1; | 237 | rc = -1; |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f9f77bee0b1b..e584cd30b0f2 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -545,12 +545,19 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) | |||
545 | 545 | ||
546 | md->prev = old; | 546 | md->prev = old; |
547 | 547 | ||
548 | if (!evlist->overwrite) | ||
549 | perf_mmap__write_tail(md, old); | ||
550 | |||
551 | return event; | 548 | return event; |
552 | } | 549 | } |
553 | 550 | ||
551 | void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) | ||
552 | { | ||
553 | if (!evlist->overwrite) { | ||
554 | struct perf_mmap *md = &evlist->mmap[idx]; | ||
555 | unsigned int old = md->prev; | ||
556 | |||
557 | perf_mmap__write_tail(md, old); | ||
558 | } | ||
559 | } | ||
560 | |||
554 | static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx) | 561 | static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx) |
555 | { | 562 | { |
556 | if (evlist->mmap[idx].base != NULL) { | 563 | if (evlist->mmap[idx].base != NULL) { |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 880d7139d2fb..206d09339306 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -89,6 +89,8 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id); | |||
89 | 89 | ||
90 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); | 90 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); |
91 | 91 | ||
92 | void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx); | ||
93 | |||
92 | int perf_evlist__open(struct perf_evlist *evlist); | 94 | int perf_evlist__open(struct perf_evlist *evlist); |
93 | void perf_evlist__close(struct perf_evlist *evlist); | 95 | void perf_evlist__close(struct perf_evlist *evlist); |
94 | 96 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0ce9febf1ba0..9f1ef9bee2d0 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -678,7 +678,6 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
678 | attr->sample_type |= PERF_SAMPLE_WEIGHT; | 678 | attr->sample_type |= PERF_SAMPLE_WEIGHT; |
679 | 679 | ||
680 | attr->mmap = track; | 680 | attr->mmap = track; |
681 | attr->mmap2 = track && !perf_missing_features.mmap2; | ||
682 | attr->comm = track; | 681 | attr->comm = track; |
683 | 682 | ||
684 | /* | 683 | /* |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index ce69901176d8..c3e5a3b817ab 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -2768,6 +2768,18 @@ int perf_session__read_header(struct perf_session *session) | |||
2768 | if (perf_file_header__read(&f_header, header, fd) < 0) | 2768 | if (perf_file_header__read(&f_header, header, fd) < 0) |
2769 | return -EINVAL; | 2769 | return -EINVAL; |
2770 | 2770 | ||
2771 | /* | ||
2772 | * Sanity check that perf.data was written cleanly; data size is | ||
2773 | * initialized to 0 and updated only if the on_exit function is run. | ||
2774 | * If data size is still 0 then the file contains only partial | ||
2775 | * information. Just warn user and process it as much as it can. | ||
2776 | */ | ||
2777 | if (f_header.data.size == 0) { | ||
2778 | pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n" | ||
2779 | "Was the 'perf record' command properly terminated?\n", | ||
2780 | session->filename); | ||
2781 | } | ||
2782 | |||
2771 | nr_attrs = f_header.attrs.size / f_header.attr_size; | 2783 | nr_attrs = f_header.attrs.size / f_header.attr_size; |
2772 | lseek(fd, f_header.attrs.offset, SEEK_SET); | 2784 | lseek(fd, f_header.attrs.offset, SEEK_SET); |
2773 | 2785 | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 1329b6b6ffe6..ce8dc61ce2c3 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <pthread.h> | 5 | #include <pthread.h> |
6 | #include "callchain.h" | 6 | #include "callchain.h" |
7 | #include "header.h" | 7 | #include "header.h" |
8 | #include "color.h" | ||
8 | 9 | ||
9 | extern struct callchain_param callchain_param; | 10 | extern struct callchain_param callchain_param; |
10 | 11 | ||
@@ -175,6 +176,18 @@ void perf_hpp__init(void); | |||
175 | void perf_hpp__column_register(struct perf_hpp_fmt *format); | 176 | void perf_hpp__column_register(struct perf_hpp_fmt *format); |
176 | void perf_hpp__column_enable(unsigned col); | 177 | void perf_hpp__column_enable(unsigned col); |
177 | 178 | ||
179 | static inline size_t perf_hpp__use_color(void) | ||
180 | { | ||
181 | return !symbol_conf.field_sep; | ||
182 | } | ||
183 | |||
184 | static inline size_t perf_hpp__color_overhead(void) | ||
185 | { | ||
186 | return perf_hpp__use_color() ? | ||
187 | (COLOR_MAXLEN + sizeof(PERF_COLOR_RESET)) * PERF_HPP__MAX_INDEX | ||
188 | : 0; | ||
189 | } | ||
190 | |||
178 | struct perf_evlist; | 191 | struct perf_evlist; |
179 | 192 | ||
180 | struct hist_browser_timer { | 193 | struct hist_browser_timer { |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 371476cb8ddc..f0692737ebf1 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -1327,8 +1327,8 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, | |||
1327 | struct perf_probe_point *ppt) | 1327 | struct perf_probe_point *ppt) |
1328 | { | 1328 | { |
1329 | Dwarf_Die cudie, spdie, indie; | 1329 | Dwarf_Die cudie, spdie, indie; |
1330 | Dwarf_Addr _addr, baseaddr; | 1330 | Dwarf_Addr _addr = 0, baseaddr = 0; |
1331 | const char *fname = NULL, *func = NULL, *tmp; | 1331 | const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp; |
1332 | int baseline = 0, lineno = 0, ret = 0; | 1332 | int baseline = 0, lineno = 0, ret = 0; |
1333 | 1333 | ||
1334 | /* Adjust address with bias */ | 1334 | /* Adjust address with bias */ |
@@ -1349,27 +1349,36 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, | |||
1349 | /* Find a corresponding function (name, baseline and baseaddr) */ | 1349 | /* Find a corresponding function (name, baseline and baseaddr) */ |
1350 | if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { | 1350 | if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { |
1351 | /* Get function entry information */ | 1351 | /* Get function entry information */ |
1352 | tmp = dwarf_diename(&spdie); | 1352 | func = basefunc = dwarf_diename(&spdie); |
1353 | if (!tmp || | 1353 | if (!func || |
1354 | dwarf_entrypc(&spdie, &baseaddr) != 0 || | 1354 | dwarf_entrypc(&spdie, &baseaddr) != 0 || |
1355 | dwarf_decl_line(&spdie, &baseline) != 0) | 1355 | dwarf_decl_line(&spdie, &baseline) != 0) { |
1356 | lineno = 0; | ||
1356 | goto post; | 1357 | goto post; |
1357 | func = tmp; | 1358 | } |
1358 | 1359 | ||
1359 | if (addr == (unsigned long)baseaddr) | 1360 | fname = dwarf_decl_file(&spdie); |
1361 | if (addr == (unsigned long)baseaddr) { | ||
1360 | /* Function entry - Relative line number is 0 */ | 1362 | /* Function entry - Relative line number is 0 */ |
1361 | lineno = baseline; | 1363 | lineno = baseline; |
1362 | else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, | 1364 | goto post; |
1363 | &indie)) { | 1365 | } |
1366 | |||
1367 | /* Track down the inline functions step by step */ | ||
1368 | while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr, | ||
1369 | &indie)) { | ||
1370 | /* There is an inline function */ | ||
1364 | if (dwarf_entrypc(&indie, &_addr) == 0 && | 1371 | if (dwarf_entrypc(&indie, &_addr) == 0 && |
1365 | _addr == addr) | 1372 | _addr == addr) { |
1366 | /* | 1373 | /* |
1367 | * addr is at an inline function entry. | 1374 | * addr is at an inline function entry. |
1368 | * In this case, lineno should be the call-site | 1375 | * In this case, lineno should be the call-site |
1369 | * line number. | 1376 | * line number. (overwrite lineinfo) |
1370 | */ | 1377 | */ |
1371 | lineno = die_get_call_lineno(&indie); | 1378 | lineno = die_get_call_lineno(&indie); |
1372 | else { | 1379 | fname = die_get_call_file(&indie); |
1380 | break; | ||
1381 | } else { | ||
1373 | /* | 1382 | /* |
1374 | * addr is in an inline function body. | 1383 | * addr is in an inline function body. |
1375 | * Since lineno points one of the lines | 1384 | * Since lineno points one of the lines |
@@ -1377,19 +1386,27 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, | |||
1377 | * be the entry line of the inline function. | 1386 | * be the entry line of the inline function. |
1378 | */ | 1387 | */ |
1379 | tmp = dwarf_diename(&indie); | 1388 | tmp = dwarf_diename(&indie); |
1380 | if (tmp && | 1389 | if (!tmp || |
1381 | dwarf_decl_line(&spdie, &baseline) == 0) | 1390 | dwarf_decl_line(&indie, &baseline) != 0) |
1382 | func = tmp; | 1391 | break; |
1392 | func = tmp; | ||
1393 | spdie = indie; | ||
1383 | } | 1394 | } |
1384 | } | 1395 | } |
1396 | /* Verify the lineno and baseline are in a same file */ | ||
1397 | tmp = dwarf_decl_file(&spdie); | ||
1398 | if (!tmp || strcmp(tmp, fname) != 0) | ||
1399 | lineno = 0; | ||
1385 | } | 1400 | } |
1386 | 1401 | ||
1387 | post: | 1402 | post: |
1388 | /* Make a relative line number or an offset */ | 1403 | /* Make a relative line number or an offset */ |
1389 | if (lineno) | 1404 | if (lineno) |
1390 | ppt->line = lineno - baseline; | 1405 | ppt->line = lineno - baseline; |
1391 | else if (func) | 1406 | else if (basefunc) { |
1392 | ppt->offset = addr - (unsigned long)baseaddr; | 1407 | ppt->offset = addr - (unsigned long)baseaddr; |
1408 | func = basefunc; | ||
1409 | } | ||
1393 | 1410 | ||
1394 | /* Duplicate strings */ | 1411 | /* Duplicate strings */ |
1395 | if (func) { | 1412 | if (func) { |
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 71b5412bbbb9..2ac4bc92bb1f 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c | |||
@@ -822,6 +822,8 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, | |||
822 | PyObject *pyevent = pyrf_event__new(event); | 822 | PyObject *pyevent = pyrf_event__new(event); |
823 | struct pyrf_event *pevent = (struct pyrf_event *)pyevent; | 823 | struct pyrf_event *pevent = (struct pyrf_event *)pyevent; |
824 | 824 | ||
825 | perf_evlist__mmap_consume(evlist, cpu); | ||
826 | |||
825 | if (pyevent == NULL) | 827 | if (pyevent == NULL) |
826 | return PyErr_NoMemory(); | 828 | return PyErr_NoMemory(); |
827 | 829 | ||
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index a85e4ae5f3ac..c0c9795c4f02 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c | |||
@@ -282,7 +282,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused, | |||
282 | 282 | ||
283 | event = find_cache_event(evsel); | 283 | event = find_cache_event(evsel); |
284 | if (!event) | 284 | if (!event) |
285 | die("ug! no event found for type %" PRIu64, evsel->attr.config); | 285 | die("ug! no event found for type %" PRIu64, (u64)evsel->attr.config); |
286 | 286 | ||
287 | pid = raw_field_value(event, "common_pid", data); | 287 | pid = raw_field_value(event, "common_pid", data); |
288 | 288 | ||
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index cc75a3cef388..95d91a0b23af 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -56,6 +56,17 @@ static void handler_call_die(const char *handler_name) | |||
56 | Py_FatalError("problem in Python trace event handler"); | 56 | Py_FatalError("problem in Python trace event handler"); |
57 | } | 57 | } |
58 | 58 | ||
59 | /* | ||
60 | * Insert val into into the dictionary and decrement the reference counter. | ||
61 | * This is necessary for dictionaries since PyDict_SetItemString() does not | ||
62 | * steal a reference, as opposed to PyTuple_SetItem(). | ||
63 | */ | ||
64 | static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObject *val) | ||
65 | { | ||
66 | PyDict_SetItemString(dict, key, val); | ||
67 | Py_DECREF(val); | ||
68 | } | ||
69 | |||
59 | static void define_value(enum print_arg_type field_type, | 70 | static void define_value(enum print_arg_type field_type, |
60 | const char *ev_name, | 71 | const char *ev_name, |
61 | const char *field_name, | 72 | const char *field_name, |
@@ -279,11 +290,11 @@ static void python_process_tracepoint(union perf_event *perf_event | |||
279 | PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); | 290 | PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); |
280 | PyTuple_SetItem(t, n++, PyString_FromString(comm)); | 291 | PyTuple_SetItem(t, n++, PyString_FromString(comm)); |
281 | } else { | 292 | } else { |
282 | PyDict_SetItemString(dict, "common_cpu", PyInt_FromLong(cpu)); | 293 | pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu)); |
283 | PyDict_SetItemString(dict, "common_s", PyInt_FromLong(s)); | 294 | pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s)); |
284 | PyDict_SetItemString(dict, "common_ns", PyInt_FromLong(ns)); | 295 | pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns)); |
285 | PyDict_SetItemString(dict, "common_pid", PyInt_FromLong(pid)); | 296 | pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid)); |
286 | PyDict_SetItemString(dict, "common_comm", PyString_FromString(comm)); | 297 | pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm)); |
287 | } | 298 | } |
288 | for (field = event->format.fields; field; field = field->next) { | 299 | for (field = event->format.fields; field; field = field->next) { |
289 | if (field->flags & FIELD_IS_STRING) { | 300 | if (field->flags & FIELD_IS_STRING) { |
@@ -313,7 +324,7 @@ static void python_process_tracepoint(union perf_event *perf_event | |||
313 | if (handler) | 324 | if (handler) |
314 | PyTuple_SetItem(t, n++, obj); | 325 | PyTuple_SetItem(t, n++, obj); |
315 | else | 326 | else |
316 | PyDict_SetItemString(dict, field->name, obj); | 327 | pydict_set_item_string_decref(dict, field->name, obj); |
317 | 328 | ||
318 | } | 329 | } |
319 | if (!handler) | 330 | if (!handler) |
@@ -370,21 +381,21 @@ static void python_process_general_event(union perf_event *perf_event | |||
370 | if (!handler || !PyCallable_Check(handler)) | 381 | if (!handler || !PyCallable_Check(handler)) |
371 | goto exit; | 382 | goto exit; |
372 | 383 | ||
373 | PyDict_SetItemString(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); | 384 | pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); |
374 | PyDict_SetItemString(dict, "attr", PyString_FromStringAndSize( | 385 | pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( |
375 | (const char *)&evsel->attr, sizeof(evsel->attr))); | 386 | (const char *)&evsel->attr, sizeof(evsel->attr))); |
376 | PyDict_SetItemString(dict, "sample", PyString_FromStringAndSize( | 387 | pydict_set_item_string_decref(dict, "sample", PyString_FromStringAndSize( |
377 | (const char *)sample, sizeof(*sample))); | 388 | (const char *)sample, sizeof(*sample))); |
378 | PyDict_SetItemString(dict, "raw_buf", PyString_FromStringAndSize( | 389 | pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( |
379 | (const char *)sample->raw_data, sample->raw_size)); | 390 | (const char *)sample->raw_data, sample->raw_size)); |
380 | PyDict_SetItemString(dict, "comm", | 391 | pydict_set_item_string_decref(dict, "comm", |
381 | PyString_FromString(thread->comm)); | 392 | PyString_FromString(thread->comm)); |
382 | if (al->map) { | 393 | if (al->map) { |
383 | PyDict_SetItemString(dict, "dso", | 394 | pydict_set_item_string_decref(dict, "dso", |
384 | PyString_FromString(al->map->dso->name)); | 395 | PyString_FromString(al->map->dso->name)); |
385 | } | 396 | } |
386 | if (al->sym) { | 397 | if (al->sym) { |
387 | PyDict_SetItemString(dict, "symbol", | 398 | pydict_set_item_string_decref(dict, "symbol", |
388 | PyString_FromString(al->sym->name)); | 399 | PyString_FromString(al->sym->name)); |
389 | } | 400 | } |
390 | 401 | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 70ffa41518f3..568b750c01f6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -256,6 +256,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) | |||
256 | tool->sample = process_event_sample_stub; | 256 | tool->sample = process_event_sample_stub; |
257 | if (tool->mmap == NULL) | 257 | if (tool->mmap == NULL) |
258 | tool->mmap = process_event_stub; | 258 | tool->mmap = process_event_stub; |
259 | if (tool->mmap2 == NULL) | ||
260 | tool->mmap2 = process_event_stub; | ||
259 | if (tool->comm == NULL) | 261 | if (tool->comm == NULL) |
260 | tool->comm = process_event_stub; | 262 | tool->comm = process_event_stub; |
261 | if (tool->fork == NULL) | 263 | if (tool->fork == NULL) |
@@ -1310,7 +1312,7 @@ int __perf_session__process_events(struct perf_session *session, | |||
1310 | file_offset = page_offset; | 1312 | file_offset = page_offset; |
1311 | head = data_offset - page_offset; | 1313 | head = data_offset - page_offset; |
1312 | 1314 | ||
1313 | if (data_offset + data_size < file_size) | 1315 | if (data_size && (data_offset + data_size < file_size)) |
1314 | file_size = data_offset + data_size; | 1316 | file_size = data_offset + data_size; |
1315 | 1317 | ||
1316 | progress_next = file_size / 16; | 1318 | progress_next = file_size / 16; |