Revision 57f0ff059e3daa4e70a811cb1d31a49968262d20 authored by Michael Petlan on 19 July 2021, 14:53:32 UTC, committed by Arnaldo Carvalho de Melo on 18 September 2021, 20:43:05 UTC
It's later supposed to be either a correct address or NULL. Without the
initialization, it may contain an undefined value which results in the
following segmentation fault:

  # perf top --sort comm -g --ignore-callees=do_idle

terminates with:

  #0  0x00007ffff56b7685 in __strlen_avx2 () from /lib64/libc.so.6
  #1  0x00007ffff55e3802 in strdup () from /lib64/libc.so.6
  #2  0x00005555558cb139 in hist_entry__init (callchain_size=<optimized out>, sample_self=true, template=0x7fffde7fb110, he=0x7fffd801c250) at util/hist.c:489
  #3  hist_entry__new (template=template@entry=0x7fffde7fb110, sample_self=sample_self@entry=true) at util/hist.c:564
  #4  0x00005555558cb4ba in hists__findnew_entry (hists=hists@entry=0x5555561d9e38, entry=entry@entry=0x7fffde7fb110, al=al@entry=0x7fffde7fb420,
      sample_self=sample_self@entry=true) at util/hist.c:657
  #5  0x00005555558cba1b in __hists__add_entry (hists=hists@entry=0x5555561d9e38, al=0x7fffde7fb420, sym_parent=<optimized out>, bi=bi@entry=0x0, mi=mi@entry=0x0,
      sample=sample@entry=0x7fffde7fb4b0, sample_self=true, ops=0x0, block_info=0x0) at util/hist.c:288
  #6  0x00005555558cbb70 in hists__add_entry (sample_self=true, sample=0x7fffde7fb4b0, mi=0x0, bi=0x0, sym_parent=<optimized out>, al=<optimized out>, hists=0x5555561d9e38)
      at util/hist.c:1056
  #7  iter_add_single_cumulative_entry (iter=0x7fffde7fb460, al=<optimized out>) at util/hist.c:1056
  #8  0x00005555558cc8a4 in hist_entry_iter__add (iter=iter@entry=0x7fffde7fb460, al=al@entry=0x7fffde7fb420, max_stack_depth=<optimized out>, arg=arg@entry=0x7fffffff7db0)
      at util/hist.c:1231
  #9  0x00005555557cdc9a in perf_event__process_sample (machine=<optimized out>, sample=0x7fffde7fb4b0, evsel=<optimized out>, event=<optimized out>, tool=0x7fffffff7db0)
      at builtin-top.c:842
  #10 deliver_event (qe=<optimized out>, qevent=<optimized out>) at builtin-top.c:1202
  #11 0x00005555558a9318 in do_flush (show_progress=false, oe=0x7fffffff80e0) at util/ordered-events.c:244
  #12 __ordered_events__flush (oe=oe@entry=0x7fffffff80e0, how=how@entry=OE_FLUSH__TOP, timestamp=timestamp@entry=0) at util/ordered-events.c:323
  #13 0x00005555558a9789 in __ordered_events__flush (timestamp=<optimized out>, how=<optimized out>, oe=<optimized out>) at util/ordered-events.c:339
  #14 ordered_events__flush (how=OE_FLUSH__TOP, oe=0x7fffffff80e0) at util/ordered-events.c:341
  #15 ordered_events__flush (oe=oe@entry=0x7fffffff80e0, how=how@entry=OE_FLUSH__TOP) at util/ordered-events.c:339
  #16 0x00005555557cd631 in process_thread (arg=0x7fffffff7db0) at builtin-top.c:1114
  #17 0x00007ffff7bb817a in start_thread () from /lib64/libpthread.so.0
  #18 0x00007ffff5656dc3 in clone () from /lib64/libc.so.6

If you look at the frame #2, the code is:

488	 if (he->srcline) {
489          he->srcline = strdup(he->srcline);
490          if (he->srcline == NULL)
491              goto err_rawdata;
492	 }

If he->srcline is not NULL (it is not NULL if it is uninitialized rubbish),
it gets strdupped and strdupping a rubbish random string causes the problem.

Also, if you look at the commit 1fb7d06a509e, it adds the srcline property
into the struct, but not initializing it everywhere needed.

Committer notes:

Now I see, when using --ignore-callees=do_idle we end up here at line
2189 in add_callchain_ip():

2181         if (al.sym != NULL) {
2182                 if (perf_hpp_list.parent && !*parent &&
2183                     symbol__match_regex(al.sym, &parent_regex))
2184                         *parent = al.sym;
2185                 else if (have_ignore_callees && root_al &&
2186                   symbol__match_regex(al.sym, &ignore_callees_regex)) {
2187                         /* Treat this symbol as the root,
2188                            forgetting its callees. */
2189                         *root_al = al;
2190                         callchain_cursor_reset(cursor);
2191                 }
2192         }

And the al that doesn't have the ->srcline field initialized will be
copied to the root_al, so then, back to:

1211 int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
1212                          int max_stack_depth, void *arg)
1213 {
1214         int err, err2;
1215         struct map *alm = NULL;
1216
1217         if (al)
1218                 alm = map__get(al->map);
1219
1220         err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent,
1221                                         iter->evsel, al, max_stack_depth);
1222         if (err) {
1223                 map__put(alm);
1224                 return err;
1225         }
1226
1227         err = iter->ops->prepare_entry(iter, al);
1228         if (err)
1229                 goto out;
1230
1231         err = iter->ops->add_single_entry(iter, al);
1232         if (err)
1233                 goto out;
1234

That al at line 1221 is what hist_entry_iter__add() (called from
sample__resolve_callchain()) saw as 'root_al', and then:

        iter->ops->add_single_entry(iter, al);

will go on with al->srcline with a bogus value, I'll add the above
sequence to the cset and apply, thanks!

Signed-off-by: Michael Petlan <mpetlan@redhat.com>
CC: Milian Wolff <milian.wolff@kdab.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Fixes: 1fb7d06a509e ("perf report Use srcline from callchain for hist entries")
Link: https //lore.kernel.org/r/20210719145332.29747-1-mpetlan@redhat.com
Reported-by: Juri Lelli <jlelli@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent ff6f41f
History
File Mode Size
libxfs
scrub
Kconfig -rw-r--r-- 6.3 KB
Makefile -rw-r--r-- 3.8 KB
kmem.c -rw-r--r-- 721 bytes
kmem.h -rw-r--r-- 2.0 KB
mrlock.h -rw-r--r-- 1.6 KB
xfs.h -rw-r--r-- 371 bytes
xfs_acl.c -rw-r--r-- 6.2 KB
xfs_acl.h -rw-r--r-- 842 bytes
xfs_aops.c -rw-r--r-- 15.9 KB
xfs_aops.h -rw-r--r-- 402 bytes
xfs_attr_inactive.c -rw-r--r-- 9.8 KB
xfs_attr_list.c -rw-r--r-- 13.2 KB
xfs_bio_io.c -rw-r--r-- 2.2 KB
xfs_bmap_item.c -rw-r--r-- 18.0 KB
xfs_bmap_item.h -rw-r--r-- 2.1 KB
xfs_bmap_util.c -rw-r--r-- 47.7 KB
xfs_bmap_util.h -rw-r--r-- 2.6 KB
xfs_buf.c -rw-r--r-- 56.4 KB
xfs_buf.h -rw-r--r-- 11.5 KB
xfs_buf_item.c -rw-r--r-- 28.6 KB
xfs_buf_item.h -rw-r--r-- 2.3 KB
xfs_buf_item_recover.c -rw-r--r-- 28.3 KB
xfs_dir2_readdir.c -rw-r--r-- 13.4 KB
xfs_discard.c -rw-r--r-- 5.5 KB
xfs_discard.h -rw-r--r-- 229 bytes
xfs_dquot.c -rw-r--r-- 35.3 KB
xfs_dquot.h -rw-r--r-- 6.3 KB
xfs_dquot_item.c -rw-r--r-- 5.2 KB
xfs_dquot_item.h -rw-r--r-- 498 bytes
xfs_dquot_item_recover.c -rw-r--r-- 5.1 KB
xfs_error.c -rw-r--r-- 12.5 KB
xfs_error.h -rw-r--r-- 3.3 KB
xfs_export.c -rw-r--r-- 5.8 KB
xfs_export.h -rw-r--r-- 1.4 KB
xfs_extent_busy.c -rw-r--r-- 15.4 KB
xfs_extent_busy.h -rw-r--r-- 1.9 KB
xfs_extfree_item.c -rw-r--r-- 21.1 KB
xfs_extfree_item.h -rw-r--r-- 2.6 KB
xfs_file.c -rw-r--r-- 37.3 KB
xfs_filestream.c -rw-r--r-- 8.7 KB
xfs_filestream.h -rw-r--r-- 788 bytes
xfs_fsmap.c -rw-r--r-- 25.9 KB
xfs_fsmap.h -rw-r--r-- 1.0 KB
xfs_fsops.c -rw-r--r-- 15.2 KB
xfs_fsops.h -rw-r--r-- 705 bytes
xfs_globals.c -rw-r--r-- 1.3 KB
xfs_health.c -rw-r--r-- 9.4 KB
xfs_icache.c -rw-r--r-- 54.9 KB
xfs_icache.h -rw-r--r-- 2.8 KB
xfs_icreate_item.c -rw-r--r-- 7.5 KB
xfs_icreate_item.h -rw-r--r-- 583 bytes
xfs_inode.c -rw-r--r-- 105.2 KB
xfs_inode.h -rw-r--r-- 16.0 KB
xfs_inode_item.c -rw-r--r-- 24.3 KB
xfs_inode_item.h -rw-r--r-- 1.8 KB
xfs_inode_item_recover.c -rw-r--r-- 14.7 KB
xfs_ioctl.c -rw-r--r-- 50.4 KB
xfs_ioctl.h -rw-r--r-- 1.5 KB
xfs_ioctl32.c -rw-r--r-- 15.0 KB
xfs_ioctl32.h -rw-r--r-- 8.0 KB
xfs_iomap.c -rw-r--r-- 35.2 KB
xfs_iomap.h -rw-r--r-- 1.2 KB
xfs_iops.c -rw-r--r-- 35.6 KB
xfs_iops.h -rw-r--r-- 589 bytes
xfs_itable.c -rw-r--r-- 11.8 KB
xfs_itable.h -rw-r--r-- 2.1 KB
xfs_iwalk.c -rw-r--r-- 20.6 KB
xfs_iwalk.h -rw-r--r-- 1.8 KB
xfs_linux.h -rw-r--r-- 6.6 KB
xfs_log.c -rw-r--r-- 111.1 KB
xfs_log.h -rw-r--r-- 4.2 KB
xfs_log_cil.c -rw-r--r-- 46.8 KB
xfs_log_priv.h -rw-r--r-- 24.8 KB
xfs_log_recover.c -rw-r--r-- 98.4 KB
xfs_message.c -rw-r--r-- 2.8 KB
xfs_message.h -rw-r--r-- 2.8 KB
xfs_mount.c -rw-r--r-- 36.3 KB
xfs_mount.h -rw-r--r-- 18.4 KB
xfs_mru_cache.c -rw-r--r-- 17.2 KB
xfs_mru_cache.h -rw-r--r-- 1.1 KB
xfs_ondisk.h -rw-r--r-- 7.8 KB
xfs_pnfs.c -rw-r--r-- 7.4 KB
xfs_pnfs.h -rw-r--r-- 692 bytes
xfs_pwork.c -rw-r--r-- 3.2 KB
xfs_pwork.h -rw-r--r-- 1.4 KB
xfs_qm.c -rw-r--r-- 45.3 KB
xfs_qm.h -rw-r--r-- 4.7 KB
xfs_qm_bhv.c -rw-r--r-- 3.6 KB
xfs_qm_syscalls.c -rw-r--r-- 13.4 KB
xfs_quota.h -rw-r--r-- 6.1 KB
xfs_quotaops.c -rw-r--r-- 6.3 KB
xfs_refcount_item.c -rw-r--r-- 18.9 KB
xfs_refcount_item.h -rw-r--r-- 2.2 KB
xfs_reflink.c -rw-r--r-- 44.1 KB
xfs_reflink.h -rw-r--r-- 2.4 KB
xfs_rmap_item.c -rw-r--r-- 18.7 KB
xfs_rmap_item.h -rw-r--r-- 2.4 KB
xfs_rtalloc.c -rw-r--r-- 36.9 KB
xfs_rtalloc.h -rw-r--r-- 5.4 KB
xfs_stats.c -rw-r--r-- 4.4 KB
xfs_stats.h -rw-r--r-- 5.7 KB
xfs_super.c -rw-r--r-- 58.6 KB
xfs_super.h -rw-r--r-- 2.3 KB
xfs_symlink.c -rw-r--r-- 11.9 KB
xfs_symlink.h -rw-r--r-- 554 bytes
xfs_sysctl.c -rw-r--r-- 5.6 KB
xfs_sysctl.h -rw-r--r-- 3.2 KB
xfs_sysfs.c -rw-r--r-- 13.6 KB
xfs_sysfs.h -rw-r--r-- 1.2 KB
xfs_trace.c -rw-r--r-- 1014 bytes
xfs_trace.h -rw-r--r-- 128.6 KB
xfs_trans.c -rw-r--r-- 32.1 KB
xfs_trans.h -rw-r--r-- 9.7 KB
xfs_trans_ail.c -rw-r--r-- 24.2 KB
xfs_trans_buf.c -rw-r--r-- 20.2 KB
xfs_trans_dquot.c -rw-r--r-- 20.5 KB
xfs_trans_priv.h -rw-r--r-- 4.6 KB
xfs_xattr.c -rw-r--r-- 4.8 KB

back to top