Patch "perf machine: Initialize srcline string member in add_location struct" has been added to the 4.19-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    perf machine: Initialize srcline string member in add_location struct

to the 4.19-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     perf-machine-initialize-srcline-string-member-in-add.patch
and it can be found in the queue-4.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 3f7bdb0bf78848520371e69ad3d2154e3117d76d
Author: Michael Petlan <mpetlan@xxxxxxxxxx>
Date:   Mon Jul 19 16:53:32 2021 +0200

    perf machine: Initialize srcline string member in add_location struct
    
    [ Upstream commit 57f0ff059e3daa4e70a811cb1d31a49968262d20 ]
    
    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@xxxxxxxxxx>
    CC: Milian Wolff <milian.wolff@xxxxxxxx>
    Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
    Fixes: 1fb7d06a509e ("perf report Use srcline from callchain for hist entries")
    Link: https //lore.kernel.org/r/20210719145332.29747-1-mpetlan@xxxxxxxxxx
    Reported-by: Juri Lelli <jlelli@xxxxxxxxxx>
    Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index ab208400ea14..4ada233b37ed 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1893,6 +1893,7 @@ static int add_callchain_ip(struct thread *thread,
 
 	al.filtered = 0;
 	al.sym = NULL;
+	al.srcline = NULL;
 	if (!cpumode) {
 		thread__find_cpumode_addr_location(thread, ip, &al);
 	} else {



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux