perf: Fix various display bugs with parent filtering
Hists that have been filtered, because they don't have callchains matching the parent filter, won't be printed. As such, hist_entry__snprintf() returns 0 for them, but we don't control this value and we always print the buffer, which might be untouched and then only made of random stack garbage. Not only does it paint the screen with barf, it also prints the callchains for these hists, even though they have been filtered, since the hist has been filtered as well. We need to check the return value of hist_entry__snprintf() and ignore the hist if it is 0, which means it didn't get any callchain matching the parent filter. This fixes the barf and the undesired callchains. Reported-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
44a54f787c
commit
58c3439083
1 changed files with 16 additions and 5 deletions
|
@ -631,9 +631,14 @@ int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
|
||||||
u64 session_total)
|
u64 session_total)
|
||||||
{
|
{
|
||||||
char bf[512];
|
char bf[512];
|
||||||
hist_entry__snprintf(self, bf, sizeof(bf), pair_hists,
|
int ret;
|
||||||
|
|
||||||
|
ret = hist_entry__snprintf(self, bf, sizeof(bf), pair_hists,
|
||||||
show_displacement, displacement,
|
show_displacement, displacement,
|
||||||
true, session_total);
|
true, session_total);
|
||||||
|
if (!ret)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return fprintf(fp, "%s\n", bf);
|
return fprintf(fp, "%s\n", bf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,6 +767,7 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
|
||||||
print_entries:
|
print_entries:
|
||||||
for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
|
for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
|
||||||
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
||||||
|
int cnt;
|
||||||
|
|
||||||
if (show_displacement) {
|
if (show_displacement) {
|
||||||
if (h->pair != NULL)
|
if (h->pair != NULL)
|
||||||
|
@ -771,8 +777,13 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
|
||||||
displacement = 0;
|
displacement = 0;
|
||||||
++position;
|
++position;
|
||||||
}
|
}
|
||||||
ret += hist_entry__fprintf(h, pair, show_displacement,
|
cnt = hist_entry__fprintf(h, pair, show_displacement,
|
||||||
displacement, fp, self->stats.total_period);
|
displacement, fp, self->stats.total_period);
|
||||||
|
/* Ignore those that didn't match the parent filter */
|
||||||
|
if (!cnt)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret += cnt;
|
||||||
|
|
||||||
if (symbol_conf.use_callchain)
|
if (symbol_conf.use_callchain)
|
||||||
ret += hist_entry__fprintf_callchain(h, fp, self->stats.total_period);
|
ret += hist_entry__fprintf_callchain(h, fp, self->stats.total_period);
|
||||||
|
|
Loading…
Reference in a new issue