BugLink: https://bugs.launchpad.net/bugs/2073603
[ Upstream commit 769e6a1e15bdbbaf2b0d2f37c24f2c53268bd21f ]
ui_browser__show() is capturing the input title that is stack allocated
memory in hist_browser__run().
Avoid a use after return by strdup-ing the string.
Committer notes:
Further explanation from Ian Rogers:
My command line using tui is:
$ sudo bash -c 'rm /tmp/asan.log*; export
ASAN_OPTIONS="log_path=/tmp/asan.log"; /tmp/perf/perf mem record -a
sleep 1; /tmp/perf/perf mem report'
I then go to the perf annotate view and quit. This triggers the asan
error (from the log file):
```
==1254591==ERROR: AddressSanitizer: stack-use-after-return on address
0x7f2813331920 at pc 0x7f28180
65991 bp 0x7fff0a21c750 sp 0x7fff0a21bf10
READ of size 80 at 0x7f2813331920 thread T0
#0 0x7f2818065990 in __interceptor_strlen
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:461
#1 0x7f2817698251 in SLsmg_write_wrapped_string
(/lib/x86_64-linux-gnu/libslang.so.2+0x98251)
#2 0x7f28176984b9 in SLsmg_write_nstring
(/lib/x86_64-linux-gnu/libslang.so.2+0x984b9)
#3 0x55c94045b365 in ui_browser__write_nstring ui/browser.c:60
#4 0x55c94045c558 in __ui_browser__show_title ui/browser.c:266
#5 0x55c94045c776 in ui_browser__show ui/browser.c:288
#6 0x55c94045c06d in ui_browser__handle_resize ui/browser.c:206
#7 0x55c94047979b in do_annotate ui/browsers/hists.c:2458
#8 0x55c94047fb17 in evsel__hists_browse ui/browsers/hists.c:3412
#9 0x55c940480a0c in perf_evsel_menu__run ui/browsers/hists.c:3527
#10 0x55c940481108 in __evlist__tui_browse_hists ui/browsers/hists.c:3613
#11 0x55c9404813f7 in evlist__tui_browse_hists ui/browsers/hists.c:3661
#12 0x55c93ffa253f in report__browse_hists tools/perf/builtin-report.c:671
#13 0x55c93ffa58ca in __cmd_report tools/perf/builtin-report.c:1141
#14 0x55c93ffaf159 in cmd_report tools/perf/builtin-report.c:1805
#15 0x55c94000c05c in report_events tools/perf/builtin-mem.c:374
#16 0x55c94000d96d in cmd_mem tools/perf/builtin-mem.c:516
#17 0x55c9400e44ee in run_builtin tools/perf/perf.c:350
#18 0x55c9400e4a5a in handle_internal_command tools/perf/perf.c:403
#19 0x55c9400e4e22 in run_argv tools/perf/perf.c:447
#20 0x55c9400e53ad in main tools/perf/perf.c:561
#21 0x7f28170456c9 in __libc_start_call_main
../sysdeps/nptl/libc_start_call_main.h:58
#22 0x7f2817045784 in __libc_start_main_impl ../csu/libc-start.c:360
#23 0x55c93ff544c0 in _start (/tmp/perf/perf+0x19a4c0) (BuildId:
84899b0e8c7d3a3eaa67b2eb35e3d8b2f8cd4c93)
Address 0x7f2813331920 is located in stack of thread T0 at offset 32 in frame
#0 0x55c94046e85e in hist_browser__run ui/browsers/hists.c:746
This frame has 1 object(s):
[32, 192) 'title' (line 747) <== Memory access at offset 32 is
inside this variable
HINT: this may be a false positive if your program uses some custom
stack unwind mechanism, swapcontext or vfork
```
hist_browser__run isn't on the stack so the asan error looks legit.
There's no clean init/exit on struct ui_browser so I may be trading a
use-after-return for a memory leak, but that seems look a good trade
anyway.
Fixes: 05e8b0804e ("perf ui browser: Stop using 'self'")
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ben Gainey <ben.gainey@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Li Dong <lidong@vivo.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Oliver Upton <oliver.upton@linux.dev>
Cc: Paran Lee <p4ranlee@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Sun Haiyong <sunhaiyong@loongson.cn>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Yanteng Si <siyanteng@loongson.cn>
Cc: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/20240507183545.1236093-2-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Portia Stephens <portia.stephens@canonical.com>
Signed-off-by: Roxana Nicolescu <roxana.nicolescu@canonical.com>
BugLink: https://bugs.launchpad.net/bugs/2068087
[ Upstream commit 2b8dbf69ec60faf6c7db49e57d7f316409ccec92 ]
The symbol__annotate2() initializes some data structures needed by TUI.
It has a logic to prevent calling it multiple times by checking if it
has the annotated source. But data type profiling uses a different
code (symbol__annotate) to allocate the annotated lines in advance.
So TUI missed to call symbol__annotate2() when it shows the annotation
browser.
Make symbol__annotate() reentrant and handle that situation properly.
This fixes a crash in the annotation browser started by perf report in
TUI like below.
$ perf report -s type,sym --tui
# and press 'a' key and then move down
Fixes: 81e57deec3 ("perf report: Support data type profiling")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20240405211800.1412920-2-namhyung@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Portia Stephens <portia.stephens@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
The 'e' key is to toggle expand/collapse the selected entry only. But
the current code has a bug that it only increases the number of entries
by 1 in the hierarchy mode so users cannot move under the current entry
after the key stroke. This is due to a wrong assumption in the
hist_entry__set_folding().
The commit b33f922651 ("perf hists browser: Put hist_entry folding
logic into single function") factored out the code, but actually it
should be handled separately. The hist_browser__set_folding() is to
update fold state for each entry so it needs to traverse all (child)
entries regardless of the current fold state. So it increases the
number of entries by 1.
But the hist_entry__set_folding() only cares the currently selected
entry and its all children. So it should count all unfolded child
entries. This code is implemented in hist_browser__toggle_fold()
already so we can just call it.
Fixes: b33f922651 ("perf hists browser: Put hist_entry folding logic into single function")
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20230731094934.1616495-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Rename the fallthrough attribute to better align with the kernel
version. Copy the definition from include/linux/compiler_attributes.h
including the #else clause. Adding the #else clause allows the tools
compiler.h header to drop the check for a definition entirely and keeps
both definitions together.
Change any __fallthrough statements to fallthrough anywhere it was used
within perf.
This allows other tools to use the same key word as the kernel.
Committer notes:
Did some missing conversions to:
builtin-list.c
Also included gtk.h before the 'fallthrough' definition in:
tools/perf/ui/gtk/hists.c
tools/perf/ui/gtk/helpline.c
tools/perf/ui/gtk/browser.c
As it is the arg name for a macro in glib.h:
/var/home/acme/git/perf-tools-next/tools/include/linux/compiler-gcc.h:16:55: error: missing binary operator before token "("
16 | # define fallthrough __attribute__((__fallthrough__))
| ^
/usr/include/glib-2.0/glib/gmacros.h:637:28: note: in expansion of macro ‘fallthrough’
637 | #if g_macro__has_attribute(fallthrough)
Reviewed-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Liam Howlett <Liam.Howlett@oracle.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Tom Rix <trix@redhat.com>
Cc: linux-sparse@vger.kernel.org <linux-sparse@vger.kernel.org>
Cc: llvm@lists.linux.dev <llvm@lists.linux.dev>
Link: https://lore.kernel.org/r/20221125154947.2163498-1-Liam.Howlett@oracle.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Especially when CONFIG_LOCKDEP and other debug configs are enabled,
Perf can print the following warning when running the "kernel lock
contention analysis" test:
Warning:
Processed 1378918 events and lost 4 chunks!
Check IO/CPU overload!
Warning:
Processed 4593325 samples and lost 70.00%!
The test already supplies -q to run in quiet mode, so extend quiet mode
to perf_stdio__warning() and also ui__warning() for consistency.
This fixes the following failure due to the extra lines counted:
perf test "lock cont" -vvv
82: kernel lock contention analysis test :
--- start ---
test child forked, pid 3125
Testing perf lock record and perf lock contention
[Fail] Recorded result count is not 1: 9
test child finished with -1
---- end ----
kernel lock contention analysis test: FAILED!
Fixes: ec685de25b ("perf test: Add kernel lock contention test")
Signed-off-by: James Clark <james.clark@arm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20221018094137.783081-2-james.clark@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
In 'perf report', entering a recursive function from inside of itself
(either directly of indirectly through some other function) results in
calling symbol__annotate2 multiple() times, and freeing the whole
disassembly when exiting from the innermost instance.
The first issue causes the function's disassembly to be duplicated, and
the latter a heap use-after-free (and crash) when trying to access the
disassembly again.
I reproduced the bug on perf 5.11.22 (Ubuntu 20.04.3 LTS) and 5.16.rc8
with the following testcase (compile with gcc recursive.c -o recursive).
To reproduce:
- perf record ./recursive
- perf report
- enter fibonacci and annotate it
- move the cursor on one of the "callq fibonacci" instructions and press enter
- at this point there will be two copies of the function in the disassembly
- go back by pressing q, and perf will crash
#include <stdio.h>
int fibonacci(int n)
{
if(n <= 2) return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
int main()
{
printf("%d\n", fibonacci(40));
}
This patch addresses the issue by annotating a function and freeing the
associated memory on exit only if no annotation is already present, so
that a recursive function is only annotated on entry.
Signed-off-by: Dario Petrillo <dario.pk1@gmail.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: stable@kernel.org
Link: http://lore.kernel.org/lkml/20220109234441.325106-1-dario.pk1@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
When the following command is executed several times, a coredump file is
generated.
$ timeout -k 9 5 perf top -e task-clock
*******
*******
*******
0.01% [kernel] [k] __do_softirq
0.01% libpthread-2.28.so [.] __pthread_mutex_lock
0.01% [kernel] [k] __ll_sc_atomic64_sub_return
double free or corruption (!prev) perf top --sort comm,dso
timeout: the monitored command dumped core
When we terminate "perf top" using sending signal method,
SLsmg_reset_smg() called. SLsmg_reset_smg() resets the SLsmg screen
management routines by freeing all memory allocated while it was active.
However SLsmg_reinit_smg() maybe be called by another thread.
SLsmg_reinit_smg() will free the same memory accessed by
SLsmg_reset_smg(), thus it results in a double free.
SLsmg_reinit_smg() is called already protected by ui__lock, so we fix
the problem by adding pthread_mutex_trylock of ui__lock when calling
SLsmg_reset_smg().
Signed-off-by: Wenyu Liu <liuwenyu7@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: wuxu.wu@huawei.com
Link: http://lore.kernel.org/lkml/a91e3943-7ddc-f5c0-a7f5-360f073c20e6@huawei.com
Signed-off-by: Hewenliang <hewenliang4@huawei.com>
Signed-off-by: yaowenbin <yaowenbin1@huawei.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Some x86 microarchitectures fuse a subset of cmp/test/ALU instructions
with branch instructions, and thus perf annotate highlight such valid
pairs as fused.
When annotated with source, perf uses struct disasm_line to contain
either source or instruction line from objdump output. Usually, a C
statement generates multiple instructions which include such
cmp/test/ALU + branch instruction pairs. But in case of assembly
function, each individual assembly source line generate one
instruction.
The 'perf annotate' instruction fusion logic assumes the previous
disasm_line as the previous instruction line, which is wrong because,
for assembly function, previous disasm_line contains source line. And
thus perf fails to highlight valid fused instruction pairs for assembly
functions.
Fix it by searching backward until we find an instruction line and
consider that disasm_line as fused with current branch instruction.
Before:
│ cmpq %rcx, RIP+8(%rsp)
0.00 │ cmp %rcx,0x88(%rsp)
│ je .Lerror_bad_iret <--- Source line
0.14 │ ┌──je b4 <--- Instruction line
│ │movl %ecx, %eax
After:
│ cmpq %rcx, RIP+8(%rsp)
0.00 │ ┌──cmp %rcx,0x88(%rsp)
│ │je .Lerror_bad_iret
0.14 │ ├──je b4
│ │movl %ecx, %eax
Reviewed-by: Jin Yao <yao.jin@linux.intel.com>
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kim Phillips <kim.phillips@amd.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https //lore.kernel.org/r/20210911043854.8373-1-ravi.bangoria@amd.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
If the disasm is empty, 's' should fail. Instead it seemingly works,
hiding the empty lines and causing an assertion error on the next time
annotate is called (from within perf report).
The problem is caused by a buffer overflow, caused by a wrong exit
condition in annotate_browser__find_next_asm_line, which checks
browser->b.top instead of browser->b.entries.
This patch fixes the issue, making annotate_browser__toggle_source
fail if the disasm is empty (nothing happens to the user).
Fixes: 6de249d66d ("perf annotate: Allow 's' on source code lines")
Signed-off-by: Riccardo Mancini <rickyman7@gmail.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Martin Liška <mliska@suse.cz>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lore.kernel.org/lkml/20210705161524.72953-1-rickyman7@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
To make the output more readable, I think it's better to remove 0's in
the output. Also the dummy event has no event stats so it just wasts
the space. Let's use the --skip-empty option to suppress it.
$ perf report --stat --skip-empty
Aggregated stats:
TOTAL events: 16530
MMAP events: 226
COMM events: 1596
EXIT events: 2
THROTTLE events: 121
UNTHROTTLE events: 117
FORK events: 1595
SAMPLE events: 719
MMAP2 events: 12147
CGROUP events: 2
FINISHED_ROUND events: 2
THREAD_MAP events: 1
CPU_MAP events: 1
TIME_CONV events: 1
cycles stats:
SAMPLE events: 719
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210427013717.1651674-5-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Right now, when Line numbers are displayed, one can't easily find a
source file that the line corresponds to.
When a source line is selected and 'l' is pressed, full source file
location is displayed in perf UI footer line. The hotkey works only for
source code lines.
Signed-off-by: Martin Liška <mliska@suse.cz>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: http://lore.kernel.org/lkml/25a6384f-d862-5dda-4fec-8f0555599c75@suse.cz
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>