LiveSession.run() synchronously blocks while polling evlist for events.
When running interactive tools or scripts from the terminal,
KeyboardInterrupt exceptions raised via Ctrl-C must propagate so the
caller can break out of the polling loop.
Previously, LiveSession caught KeyboardInterrupt with an empty pass
statement, swallowing the exception and preventing calling scripts from
detecting the interrupt cleanly. Remove the empty handler so calling
scripts receive KeyboardInterrupt and can perform clean teardown.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Add support for Intel PT call_return events and itrace options to the
perf Python extension so standalone Python scripts can decode and
inspect low-level instruction traces.
Specifically:
- Add a call_return callback parameter and itrace option string to
perf.session, treating explicit None (Py_None) callbacks as omitted.
- Expose the perf.call_return object with db_id, parent_id, insn_count,
cyc_count, comm, pid, tid, call_time, return_time, branch_count,
call_ref, return_ref, flags, and call_path (resolved as a
perf.callchain ordered from outermost caller to callee, populating
frame->map and frame->sym so call_path entries expose resolved symbol
and DSO names).
- Export perf.CALL_RETURN_NO_CALL, perf.CALL_RETURN_NO_RETURN, and
perf.CALL_RETURN_NON_CALL flag constants.
- Expose session.e_machine and session.is_64_bit properties, preferring
recorded thread ELF machines (perf_session__e_machine) over perf_env
so pipe-mode traces do not prematurely cache host bitness.
- Support optional vmlinux, kallsyms, and symfs symbol configuration
parameters (and PERF_SYMBOL_VMLINUX, PERF_SYMBOL_KALLSYMS,
PERF_SYMBOL_SYMFS environment fallbacks) in perf.session, resetting
symbol_conf pointers and freeing vm_tm_corr_args, cpu_bitmap, and
ptime_range in pyrf_session__delete().
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Expose destination address location components (addr_dso, addr_symbol,
addr_sym_offset), branch/transaction metrics (branch_type, in_tx,
flags, transaction), machine_pid, vcpu, sym_offset, and context_switch
callbacks directly to the Python extension.
Also include supporting fixes and infrastructure updates in
util/python.c and perf.pyi:
- Support fetching sym_offset on resolved sample symbols.
- Populate sample machine_pid and vcpu from evlist__id2sid() when
perf_guest is enabled, and resolve samples against the matching guest
or host machine.
- Expose next_prev_pid and next_prev_tid on switch_event only for
PERF_RECORD_SWITCH_CPU_WIDE records (returning None otherwise).
- Wire up tracing_data in pyrf_session__new() and update perf.pyi type
stubs (including srccode() and insn() return types).
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Add module docstrings to counting.py, tracepoint.py, and twatch.py. This
satisfies pylint's missing-module-docstring check and prepares these
existing standalone scripts in tools/perf/python/ for the later commit
in this series ("perf script: Support standalone scripts and remove
embedded scripting"), which updates 'perf script -l' to scan
tools/perf/python/ and display each script's module docstring:
```
$ perf script -l
List of available scripts:
...
counting
Example for counting perf events.
...
tracepoint
Example showing how to enable a tracepoint and access its fields.
twatch
Example to show how to enable a software event and track
context switches.
...
```
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Clean up pylint warnings in tracepoint.py so that it passes pylint
without warning suppression comments:
- Catch ImportError instead of bare 'except:' (W0702: bare-except) when
importing setproctitle.
- Remove unnecessary trailing semicolon (W0301: unnecessary-semicolon)
after evlist.enable().
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Clean up pylint warnings in treport.py so that it passes pylint without
warning suppression comments:
- Replace broad 'except Exception:' clauses (W0718:
broad-exception-caught) with specific exception tuples.
- Pass both pid and sample_tid to session.find_thread() so guest and
process threads are resolved accurately.
- Rename parameter 'args' to 'pos_args' in FlameGraph.__init__() to
avoid shadowing the outer scope variable 'args' (W0621:
redefined-outer-name).
- Clear session = None in a finally block after session.process_events()
to break the C perf_session reference cycle before launching the TUI.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Replace bare 'except:' clauses (pylint W0702: bare-except) in ilist.py
with specific exception tuples (OSError, ValueError, RuntimeError,
TypeError, KeyError) and use a safe '.get("name", "")' sort key in
IListApp.compose() so that ilist.py passes pylint without warning
suppression comments and handles unnamed PMU events gracefully.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Update pyrf_session__find_thread() in util/python.c to accept an
optional tid parameter (defaulting to pid) and return None instead of
raising TypeError when a thread is not found in the session machines.
Update perf.pyi to match:
- Set session.find_thread() signature to (pid: int, tid: int = -1) ->
Optional[thread].
- Update callchain_node.symbol and callchain_node.dso to str (the C
getters return "[unknown]" fallback strings rather than None) and add
__iter__() to callchain.
Also update treport.py to handle Optional[thread] returned by
session.find_thread().
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Update the PyArg_ParseTupleAndKeywords format string for
pyrf__syscall_name() and pyrf__syscall_id() from "i|$i" to "i|i" (and
"s|$i" to "s|i"), allowing elf_machine to be passed as an optional
positional argument as well as a keyword argument. Update syscall_id()
and syscall_name() in perf.pyi to match, and set the return type of
syscall_name() to Optional[str] as unknown syscall numbers return None.
Also expose perf_env__arch_strerrno() as perf.arch_strerrno(err,
elf_machine=None) so standalone Python scripts can resolve
architecture-specific errno names directly from the auto-generated
trace beauty tables instead of maintaining duplicate errno dictionaries
in Python. Tighten the macro pattern in arch_errno_names.sh to
E[A-Z0-9]+ so compiler -D flags containing underscores (such as LLVM's
-DEXPERIMENTAL_KEY_INSTRUCTIONS=1) do not shadow EPERM (1), and add
EM_SPARC32PLUS alongside EM_SPARC and EM_SPARCV9.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
__synthesize_schedstat_domain() uses event after zalloc() without
checking for allocation failure, unlike __synthesize_schedstat_cpu().
If zalloc() fails and returns NULL, dereferencing ds->header.type
immediately crashes with a segmentation fault:
Program received signal SIGSEGV, Segmentation fault.
0x00005555558aed8a in __synthesize_schedstat_domain ()
#0 0x00005555558aed8a in __synthesize_schedstat_domain ()
#1 0x00005555558b889a in perf_event__synthesize_schedstat ()
#2 0x000055555563c397 in cmd_sched ()
#3 0x00005555556583a1 in handle_internal_command ()
#4 0x00005555555bf739 in main ()
perf_event__synthesize_schedstat() already treats a NULL event as an
error and cleans up, so return NULL when the allocation fails.
After this fix, an allocation failure returns NULL safely, allowing the
caller to exit gracefully without crashing:
[ perf sched stats: Failed !! ]
Fixes: c3030995f2 ("perf sched stats: Add record and rawdump support")
Signed-off-by: Hui Su <sh_def@163.com>
Cc: Swapnil Sapkal <swapnil.sapkal@amd.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
perf's build only refused interpreters older than 3.6, the check added
when jevents.py started using f-strings, and jevents.py carried a
removesuffix() shim to stay usable on them.
The kernel itself requires Python 3.9.x since 5e25b972a2 ("docs:
changes: update Python minimal version"), so tools in the tree are
expected to work with it, and staying compatible with older
interpreters stopped paying off:
- the PEP 585 generics, list[...], used by the type annotations in
jevents.py and util/setup.py are only subscriptable from Python 3.9
and, being evaluated at import or definition time, they break the
build on RHEL 8's python3.6.8 with:
TypeError: 'type' object is not subscriptable
- ProcessPoolExecutor(initializer=, initargs=) requires Python 3.7, so
generating pmu-events.c fails there as well.
Rather than spreading version guards and typing.List() workarounds for
interpreters that cannot be supported anyway, make 3.9 the floor: ask
for it once in Makefile.config and use the result in both places that
run python while building, jevents generation and the python binding,
as the binding is still built when NO_JEVENTS=1 skips the generation
check, and drop the removesuffix() shim, since str.removesuffix() was
added in 3.9.
RHEL 8 is in feature freeze, so those wanting a new perf and its python
features have to vendor a newer interpreter, just as
Documentation/process/changes.rst already asks for the kernel itself.
Tested with Python 3.9.22: perf builds, generating pmu-events.c and the
python binding, with byte for byte identical output to the build made
with the shim, while Python 3.8.20 and 3.6.15 are rejected with the
"older than 3.9" error, by the jevents check in a regular build and by
the binding check when NO_JEVENTS=1 makes them sail past it, where they
used to die on the TypeError from util/setup.py. With NO_JEVENTS=1 and
NO_LIBPYTHON=1 no interpreter runs while building, so neither check
applies. vermin reports no perf build file as requiring more than 3.9,
the only offender being the runtime script
scripts/python/mem-phys-addr.py, which the build doesn't run.
Suggested-by: Ian Rogers <irogers@google.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Cc: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
IBS events with exclude_{user,kernel} bits, as used for per-thread
recording when kernel samples are not allowed, are rejected on hardware
without the privilege filter, so per-thread 'perf mem record' fails on
AMD:
$ perf mem record -o /dev/null -- true
Failure to open event 'ibs_op/ldlat=0/u' on PMU 'ibs_op' which will be removed.
Kernel v6.14 added swfilt, a software privilege filter exposed as the
'swfilt' format term, making those events usable per-thread. Give the
ibs_op memory events extra tables with the term, selected in
perf_pmu__arch_init() when the PMU exposes it, keeping the names that
need system wide mode otherwise; the knowledge that IBS needs this
stays in the arch code.
Suggested-by: Namhyung Kim <namhyung@kernel.org>
Suggested-by: Ravi Bangoria <ravi.bangoria@amd.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Reviewed-by: Ravi Bangoria <ravi.bangoria@amd.com>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The data type profiling per-sample stream keys cross-CPU contention on
sample->cpu, which without PERF_SAMPLE_CPU is the "no CPU info"
sentinel, making same-instance accesses from different cores
indistinguishable from same-CPU traffic. 'perf mem record' already
passes -d and -W to the record parser, add --sample-cpu and document it
in perf-mem(1).
Also grow rec_argv: the new entry overflows it on PMUs with separate
load and store events, as the space for the fixed arguments was not
reserved.
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Members are added recursively, and a broken DIE can make a member's
type point back at one of its own ancestors, recursing until the stack
is gone; nothing usable comes out of nesting members 32 deep anyway, so
stop there, marking the member as truncated and giving up on member
types that don't resolve.
The check is where the children of an aggregate would be expanded, so
only struct/union members are marked as truncated.
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
'perf report -s type' hangs burning CPU on the dwz compressed debug
info of libz.so.1 (zlib-ng): die_collect_vars() saves the
dwarf_dieoffset() of the type DIE, which is relative to the file it
lives in - the dwz alt file for the types shared by more than one CU -
and update_var_state() resolves that offset in the main debug file,
parsing whatever is at it, here a typedef whose DW_AT_type refers to
itself.
Record whether the type DIE came from the alt file and resolve the
offset with die_get_type_die() in that file, with no fallback.
Fixes: 06b2ce7538 ("perf annotate-data: Maintain variable type info")
Fixes: 55ee3d005d ("perf annotate-data: Add a cache for global variable types")
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
dwarf_dieoffset() is relative to the file the DIE is in, so an offset
saved by die_collect_vars()/die_collect_global_vars() is only
meaningful in that file: add die_same_file(), comparing the Dwarf each
DIE's CU belongs to, and die_get_type_die(), resolving the offset in it
with the saved tag as a sanity check. Resolving the offset in the main
file instead parses whatever is at it when it came from the dwz common
file.
dwarf_cu_getdwarf() is new in elfutils 0.160, so the libdw feature test
probes for it and Makefile.config says 0.160.
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
A DIE parsed at an offset that is not the start of a DIE can have a
DW_AT_type that refers back to itself, making the typedef/qualifier
chases in die_get_real_type(), die_get_pointer_type() and
die_get_typename_from_type() spin forever; 'perf report -s type' did
that on the dwz compressed debug info of zlib-ng (libz.so.1).
No sane typedef/qualifier chain is 32 DIEs long, so give up on the type
with a pr_debug instead of hanging.
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The grep to match cgroup name in metric output assumes no leading / on
the cgroup name, however, cgroups in /proc/self/cgroup may have a
leading /. Strip the / if it exists to avoid failures to match the
cgroup name in the perf stat output.
Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The declaration of the Rust helper test_rs() uses "uint", a BSD-ism
that lives in <sys/types.h>, so on glibc it is only visible by
accident: glibc's <stdlib.h> includes <sys/types.h>, where uint is
exposed under __USE_MISC, which is on by default.
musl does none of that: its <stdlib.h> doesn't include <sys/types.h>
and it typedefs uint there only when _GNU_SOURCE/_BSD_SOURCE is
defined, while nothing else in this translation unit includes
<sys/types.h>. Building it on Alpine therefore fails with:
tests/workloads/code_with_type.c:9:21: error: unknown type name 'uint'; did you mean 'int'?
tests/workloads/code_with_type.c:39:17: error: implicit declaration of function 'test_rs' [-Wimplicit-function-declaration]
The second error is a consequence of the first one: with the
declaration at line 9 rejected, the call at line 39 has no prototype,
which is an error since gcc 14.
The breakage is only visible when rustc is present, because
tests/workloads/Build adds code_with_type.o when CONFIG_RUST_SUPPORT
is detected, and tools/build/feature only checks for "rustc
--version". That is why alpine:3.23 and alpine:3.24 fail while
alpine:3.22 and alpine:edge, lacking rustc, build fine and hide it.
Use unsigned int, which needs no header at all.
Fixes: 2e05bb52a1 ("perf test workload: Add code_with_type test workload")
Reviewed-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Dmitrii Dolgov <9erthalion6@gmail.com>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Two calloc() calls in the numa benchmark lack NULL return checks,
leading to potential NULL pointer dereferences on allocation failure:
1. worker_process(): the allocated `pthreads` array is used in the
following for-loop via pthreads[t] without checking for NULL.
2. __bench_numa(): the allocated `pids` array is used in the following
for-loop via pids[i] without checking for NULL.
Add BUG_ON() checks after each calloc(), consistent with the existing
NULL check style used elsewhere in the same file (e.g., node_present
and nodes allocations).
Signed-off-by: longlong yan <yanlonglong@kylinos.cn>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The PMU CPU map has different semantics for core and uncore PMUs.
For core PMUs, pmu_cpus contains the CPUs on which the event can be
opened. Intersect the user-requested CPU map with the PMU CPU map to
reject CPUs unsupported by the PMU.
For uncore PMUs, pmu_cpus is read from the PMU's cpumask sysfs attribute,
which lists the default CPU to open the event on per socket/die, not the
set of CPUs it can only be opened on. The user-requested CPU may override
these defaults, and the driver can redirect the event to the appropriate
control CPU.
Currently, __perf_evlist__propagate_maps() intersects the user-requested
CPU map with pmu_cpus for all PMUs. If the user-requested CPU is not in
pmu_cpus, the intersection becomes empty and the evsel is removed before
perf_event_open() is called.
Add evsel->is_pmu_uncore, set once from pmu->is_uncore at parse time,
to skip the intersection for uncore PMUs. Core PMUs, and other
non-core PMUs such as software events, breakpoints, or tracepoints,
continue to be restricted to their PMU CPU map.
Fixes: 811082e4b6 ("perf parse-events: Support user CPUs mixed with threads/processes")
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Nia Su <nia.su@sifive.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Exercise the function view without driving a terminal now that it has
a stdio path. Keep the existing datasym record/report coverage and make a
separate recording of the contended locks used by the futex hash benchmark.
Always check the function table headers, table replacement, missing-iaddr
diagnostic, and conflicting options. A machine can support c2c recording
without capturing a contended sample, so report a skip when the hierarchy
is empty rather than treating hardware sampling variance as a failure.
When samples are available, check generic row shapes for all three
hierarchy levels, their expanded fold signs, cacheline addresses, and the
absence of trailing whitespace in the table body.
Reviewed-by: Tianyou Li <tianyou.li@intel.com>
Reviewed-by: Wangyang Guo <wangyang.guo@intel.com>
Signed-off-by: Jiebin Sun <jiebin.sun@intel.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The function view is currently TUI-only, so it cannot be used by builds
without SLANG support, when output is piped, or from a script. Add a
--function option that prints the fully expanded three-level hierarchy to
stdout.
Keep the stdio renderer in builtin-c2c.c and reuse the common function-view
model introduced by the merged series. Export only the coalescing-field
capability check from the model, preserving the util/UI boundary and
leaving the TUI object in libperf-ui.a.
Stop padding the final identity column in symbol_view_entry(). The generic
formatter pads non-final columns but deliberately leaves the final column
unpadded, avoiding trailing whitespace in function-view table rows. The TUI
remains unchanged because its browser clears the rest of each rendered row.
--function implies --stdio and is rejected together with --stats. Validate
the iaddr requirement before processing events. Return function-view build
failures from the report command, and preserve TUI browser errors when
converting the display helpers to return a status.
Committer notes:
root@x2:~# uname -r
7.2.5-200.fc44.x86_64
root@x2:~# rpm -q kernel-debuginfo
kernel-debuginfo-7.2.5-200.fc44.x86_64
root@x2:~# perf c2c record perf bench futex hash -t 4 -r 1 -s > /dev/null 2>&1
root@x2:~# perf c2c report --stdio --function | grep "Functions Table" -A25
Shared Data Functions Table
=================================================
#
# Cycles Store
# % count Function / Contending function / Cacheline
# ......... ....... ..............................
#
- 47.89% 703 - [k] _raw_spin_lock
322 - [k] _raw_spin_lock
24 0xffff8b6dcbadf040
23 0xffff8b6dcbadf2c0
23 0xffff8b6dcbadf080
23 0xffff8b6dcbadf380
22 0xffff8b6dcbadf280
22 0xffff8b6dcbadf140
22 0xffff8b6dcbadf340
21 0xffff8b6dcbadf300
21 0xffff8b6dcbadf400
20 0xffff8b6dcbadf1c0
19 0xffff8b6dcbadf3c0
19 0xffff8b6dcbadf180
19 0xffff8b6dcbadf0c0
17 0xffff8b6dcbadf100
16 0xffff8b6dcbadf240
11 0xffff8b6dcbadf200
205 - [k] futex_q_unlock
root@x2:~#
Reviewed-by: Tianyou Li <tianyou.li@intel.com>
Reviewed-by: Wangyang Guo <wangyang.guo@intel.com>
Signed-off-by: Jiebin Sun <jiebin.sun@intel.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The workload path leaves err at 0 and returns, so the test exits 0 and is
reported as a pass even though nothing was recorded and neither report
invocation ran. The check_c2c_support() path above it already sets err=2.
Set err=2 there as well so a failing workload is reported as a skip.
Fixes: ac881007c4 ("perf tests c2c: Add a basic c2c")
Reviewed-by: Tianyou Li <tianyou.li@intel.com>
Reviewed-by: Wangyang Guo <wangyang.guo@intel.com>
Signed-off-by: Jiebin Sun <jiebin.sun@intel.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The default coalesce fields dropped pid in favor of iaddr, but the man
page still documents the old pid,iaddr default. Update it to match the
command.
Fixes: 423701a0c8 ("perf c2c: Change the default coalesce setup")
Reviewed-by: Tianyou Li <tianyou.li@intel.com>
Reviewed-by: Wangyang Guo <wangyang.guo@intel.com>
Signed-off-by: Jiebin Sun <jiebin.sun@intel.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The output_name variable is only used within builtin-sched.c for the
stats subcommand, so declare it static. This fixes a sparse warning:
builtin-sched.c:4140:12: warning: symbol 'output_name' was not
declared. Should it be static?
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: nanshuaibo <nanshuaibo811@163.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Fix typos in comments, reported by scripts/checkpatch.pl using the
misspelling list in scripts/spelling.txt. Only touches comments, no
code changes.
Assisted-by: Cursor:claude-opus-5
Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Drop the word written twice, reported by checkpatch.pl as a possible
repeated word.
Only the message text changes, no code changes.
Assisted-by: Cursor:claude-opus-5
Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
procfs__read_str() allocates the buffer it hands back and
thread__set_comm() only stores an interned copy of the string, so the
caller owns the buffer. thread__set_comm_from_proc() freed it when the
read came back empty but not once it had been used, leaking it on
every successful call.
Free it on both paths. The empty read still returns -1, err being
untouched in that case.
Found with leak sanitizer while running 'perf trace':
Direct leak of 7 byte(s) in 1 object(s) allocated from:
#1 io__getdelim fs/../io.h:179
#2 filename__read_str fs/fs.c:365
#3 procfs__read_str fs/fs.c:402
#4 thread__set_comm_from_proc util/thread.c:297
#5 syscall_arg__scnprintf_pid trace/beauty/pid.c:15
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
trace__symbols_init() creates the host machine with machine__new_host(),
which allocates a struct machine, but trace__symbols__exit() released it
with machine__exit(). That tears down the contents of the machine and
leaves the allocation itself behind, so use machine__delete(), which
does both. The replay path points trace->host at the machine embedded in
the session and never reaches here, so nothing else is affected.
The leak was hidden from leak sanitizer because trace__symbols_init()
passes the machine to trace_event__register_resolver(), which stores it
as the private pointer of the global tep handle. The handle kept the
machine reachable for as long as the process lived, so it was only once
the handle started being freed that this was reported:
Direct leak of 1256 byte(s) in 1 object(s) allocated from:
#1 __machine__new_host util/machine.c:135
#2 machine__new_host util/machine.c:155
#3 trace__symbols_init builtin-trace.c:2105
#4 trace__run builtin-trace.c:4759
#5 cmd_trace builtin-trace.c:6091
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The tep handle behind trace_event__tp_format() is a process wide cache
of the running kernel's tracepoint formats and nothing ever released
it, as the comment above it had noted since the code was added.
Add trace_event__exit() and call it from run_builtin() next to the
existing perf_config__exit(). By then the builtin has returned, so the
tep_event pointers it handed out, such as the ones cached in
evsel->tp_format, are no longer reachable.
Note that this does not silence every libtraceevent report under
leak sanitizer. Parsing a print fmt drops a token inside the library
itself, and as those allocations are not linked into the handle,
freeing the handle cannot reclaim them.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tp_format() read and parsed the format file on every call. Each parse
registers another tep_event with the global tep handle, and
libtraceevent has no way to free an individual event, only the whole
handle, so a repeated lookup of the same tracepoint both redoes the
work of reading and parsing the file and leaves a duplicate behind for
the rest of the session.
Ask the handle for the event first with tep_find_event_by_name() and
only fall back to reading the format file when it has not been parsed
yet. The handle holds formats for the running kernel alone, so a name
that is found is the same format that would have been read.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
trace_event__tp_format() encoded failure with ERR_PTR() while
trace_event__tp_format_id() returned a plain NULL when tep_find_event()
found nothing, and tp_format() itself returned NULL when
tep_parse_format() failed, as its return value was discarded. Callers
test with IS_ERR(), which NULL does not satisfy, so those two failures
were taken for success. In syscall__read_info() that leads straight to:
if (IS_ERR(sc->tp_format)) {
...
return err;
}
if (syscall__alloc_arg_fmts(sc, sc->tp_format->format.nr_fields - 1))
which dereferences NULL when a format file fails to parse.
Mixing encoded error pointers with pointers that are compared against
NULL is what allows that to happen, so drop ERR_PTR() here and report
failures the way the rest of these paths already expect, by returning
NULL with errno set. evsel__tp_format() no longer has to translate the
error back into errno before printing it with %m, and the remaining
callers become NULL tests.
syscall__scnprintf_args() gains back its fallback of printing raw
arguments: it asked for IS_ERR(sc->tp_format), but syscall__read_info()
had already replaced the error pointer with NULL, so the branch could
never be taken.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
thread__e_machine_endian() decides whether a thread is live, and so
whether to read /proc/pid/exe rather than fall back to the perf.data
environment, by recovering the session from the machine:
session = container_of(machine->machines, struct perf_session,
machines);
is_live = !session->data;
That only holds when the struct machines is the one embedded in a struct
perf_session. It is not the only one. aslr_tool keeps its own in struct
aslr_tool, and hists_cumulate, hists_filter, hists_link, hists_output
and thread-maps-share each put one on the stack. For those the
container_of subtracts offsetof(struct perf_session, machines) from an
address that was never inside a session, and the following load of
session->data reads outside the object, which is what ASan reports.
Replace the derivation with an explicit link. machines__init() takes the
owning session, or NULL when the machines is standalone, and
thread__e_machine_endian() reads it back through machines__session().
A NULL session is treated as live. The tests use synthetic pids that
have no /proc entry, so the read fails there and the e_machine falls
back to EM_HOST as before, rather than being decided by whatever the
out of bounds read happened to return. perf inject registers its
session with the aslr tool once the session exists, before any event is
processed, so that tool keeps reporting file based threads as not live.
Fixes: 70351029b5 ("perf thread: Add support for reading the e_machine type for a thread")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
--symfs=<dir>,flat documents itself as matching only the base name, so a
debuginfo lookup for /usr/lib/x86_64-linux-gnu/libc.so.6 should land on
<dir>/libc.so.6.debug. It lands on
<dir>/debug/usr/lib/x86_64-linux-gnu/libc.so.6.debug instead, because the
layout is applied to a fixed prefix and the file name arrives afterwards:
len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
snprintf(filename + len, size - len, "%s.debug", dso__long_name(dso));
perf_basename() only ever sees "/usr/lib/debug", so neither layout comes
out of it.
Compose the path as it would appear on the profiled system and join it
once, which puts the layout on the whole name. That covers
FEDORA_DEBUGINFO, UBUNTU_DEBUGINFO, MIXEDUP_UBUNTU_DEBUGINFO,
OPENEMBEDDED_DEBUGINFO and BUILDID_DEBUGINFO, plus the same composition in
build_id_cache__find_debug().
BUILDID_DEBUGINFO needs one more step: the build id cache splits the first
two characters of the build id off into a directory name, so the basename
of the hierarchy path is only part of the build id. Name the flat file
after the whole build id.
dso__disassemble_filename() passes a path from perf's own build id cache
rather than one on the profiled system, and every entry there is named
"elf" or "debug". Use path__join() so the layout does not apply.
With --symfs /s,flat the lookups are now /s/libc.so.6, /s/libc.so.6.debug,
/s/sleep and /s/<build id>.debug. hierarchy is unchanged.
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/help-unknown-cmd.h has been empty and unused ever since
it was added to the kernel in commit 5feaac248a ("perf tools: Move
help_unknown_cmd() to its own file") to its own file"). Remove it.
Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
On ARM the #slots literal may or may not be present, it won't be present
on x86. As it is missing it causes the ampereone and ampereonex PMU
metric tests to fail when run say on x86.
Extend the fake_pmu logic so that in these test cases we fake the
unknown literals like #slots as 1.0.
When building with JEVENTS_ARCH=all the ampere metric tests no longer
fail.
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Currently the leader sampling test looks for "cycles:" string to match
the event and retrieve the value before the event name. But it won't
work on hybrid systems as the event name is different like below.
$ perf script | grep -m 10 brstack
perf 3322152 1873980.978431: 625379 cpu_atom/cycles/: 558200cc40cf brstack_bench+0x31 (/home/namhyung/project/linux/tools/perf/perf)
perf 3322152 1873980.978431: 625379 cpu_atom/cycles/: 558200cc40cf brstack_bench+0x31 (/home/namhyung/project/linux/tools/perf/perf)
perf 3322152 1873980.978598: 612177 cpu_atom/cycles/: 558200cc4082 brstack_foo+0x17 (/home/namhyung/project/linux/tools/perf/perf)
perf 3322152 1873980.978598: 612177 cpu_atom/cycles/: 558200cc4082 brstack_foo+0x17 (/home/namhyung/project/linux/tools/perf/perf)
perf 3322152 1873980.978762: 591859 cpu_atom/cycles/: 558200cc403d brstack_bar+0x0 (/home/namhyung/project/linux/tools/perf/perf)
perf 3322152 1873980.978762: 591859 cpu_atom/cycles/: 558200cc403d brstack_bar+0x0 (/home/namhyung/project/linux/tools/perf/perf)
perf 3322152 1873980.978948: 628505 cpu_atom/cycles/: 558200cc403e brstack_bar+0x1 (/home/namhyung/project/linux/tools/perf/perf)
perf 3322152 1873980.978948: 628505 cpu_atom/cycles/: 558200cc403e brstack_bar+0x1 (/home/namhyung/project/linux/tools/perf/perf)
perf 3322152 1873980.979146: 669816 cpu_atom/cycles/: 558200cc40e5 brstack_bench+0x47 (/home/namhyung/project/linux/tools/perf/perf)
perf 3322152 1873980.979146: 669816 cpu_atom/cycles/: 558200cc40e5 brstack_bench+0x47 (/home/namhyung/project/linux/tools/perf/perf)
But we can control the output format of perf script using -F option. So
we knows where the period is in the output. To filter by symbol name,
"ip" and "sym" fields are required as well.
$ perf script -F period,ip,sym | grep -m 10 brstack
625379 558200cc40cf brstack_bench
625379 558200cc40cf brstack_bench
612177 558200cc4082 brstack_foo
612177 558200cc4082 brstack_foo
591859 558200cc403d brstack_bar
591859 558200cc403d brstack_bar
628505 558200cc403e brstack_bar
628505 558200cc403e brstack_bar
669816 558200cc40e5 brstack_bench
669816 558200cc40e5 brstack_bench
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
I noticed it failed for leader sampling tests on Broadwell. It's
because the period of groups members are a little bit different. Maybe
there's an hardware issue but anyway it's close enough to treat them as
same. I printed the value like below.
$ perf test record
...
prev: 462507, curr: 462506
prev: 494783, curr: 494782
prev: 454350, curr: 454349
prev: 502782, curr: 502781
prev: 566693, curr: 566692
prev: 606558, curr: 606557
prev: 559770, curr: 559769
prev: 595737, curr: 595736
prev: 643386, curr: 643385
prev: 663672, curr: 663671
prev: 620622, curr: 620621
prev: 650419, curr: 650418
Leader sampling [Failed inconsistent cycles count]
Let's update the logic to compare values to allow 1% of errors.
Also I think it should compare only if sees the non-leader samples so
split the check of (($index % 2)).
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
'perf record' with multithreads would create a data directory instead of
a file. But the cleanup and retry logic expect a file and try to delete
them with 'rm -f' which would fail. Add '-r' flag to remove
directories.
rm: cannot remove '/tmp/__perf_test.perf.data.ZVHTw.old': Is a directory
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The ProcessPoolExecutor is created without max_workers, so
concurrent.futures defaults to one worker per CPU and forks all of them
when the first task is submitted. Each worker costs the parent a few
file descriptors. For systems with high core-count processors like the
AMD EPYC 9996, the pool can easily exhaust RLIMIT_NOFILE as seen below.
File ".../multiprocessing/popen_fork.py", line 65, in _launch
child_r, parent_w = os.pipe()
OSError: [Errno 24] Too many open files
The error is reported, but jevents.py does not exit. The workers that
did start stay blocked waiting for work and are never joined, so the
build eventually hangs. Other targets keep building in the meantime,
leaving the traceback several lines above the point where the build
stalls.
Limit the pool instead of sizing it against the descriptor limit, which
would mean relying on how many descriptors concurrent.futures needs for
each worker. At least for recent AMD EPYC processors, reading the JSON
files does not need many workers to be fast and things typically stop
scaling beyond 32 workers. Hence, a small upper bound keeps the speedup
and stays well inside any usable limit.
Fixes: eaab2eb09d ("perf pmu-events: Parallelize JSON and metric pre-computation in jevents.py")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
In symbol__disassemble_llvm(), after calling llvm_addr2line(), if the
subsequent disasm_line__new() fails, the code directly jumps to 'err'
without freeing args->fileloc, leading to a memory leak.
Fix this by explicitly calling free(args->fileloc) before jumping to the
error handling path when disasm_line__new() fails.
Fixes: 0488568178 ("perf annotate: LLVM-based disassembler")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
Cc: Steinar H. Gunderson <sesse@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
loongarch_call__parse() dereferences the return value of strchr()
without NULL check:
name = strchr(endptr, '<');
name++;
When objdump output for a 'bl' (branch-and-link) instruction does not
contain a symbol name delimited by '<' and '>' (e.g., when the call
target has no associated symbol), strchr() returns NULL, and the
subsequent name++ produces a wild pointer (0x1). This leads to a
segmentation fault when strchr() is later called with this invalid
pointer:
#0 __strchr_lasx () from /lib64/libc.so.6
#1 loongarch_call__parse () at arch/loongarch/annotate/instructions.c:29
#2 disasm_line__init_ins () at util/annotate.c:1205
...
The objdump line triggering the crash looks like:
bl 98824 # 0x9000000000641ea0
Note the absence of "<function_name>" after the address.
Rather than aborting parse with -1 (which would clear dl->ins.ops and
lose the is_call attribute, preventing the TUI from drawing branch
arrows and navigating the call), follow the same pattern as the generic
call__parse() in util/disasm.c: when the symbol name is absent, jump to
the address-based symbol lookup so that ops->target.sym can still be
resolved via maps__find_ams() using the already-parsed target address.
This preserves is_call semantics and keeps TUI navigation working.
Reviewed-by: Ming Wang <wangming01@loongson.cn>
Tested-by: WANG Rui <wangrui@loongson.cn>
Signed-off-by: Jianping Liu <frankjpliu@tencent.com>
Acked-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Shellcheck follows sourced scripts when -a is provided, but only when
that file is also provided on the command line along with the one being
checked. We only ever provide one file at a time to shellcheck, so -a
does nothing.
Improve coverage by following sources using the script's directory as
the base path.
Signed-off-by: James Clark <james.clark@linaro.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The minimum required shellcheck version treats paths with leading
variables as starting from the script's current directory, so shellcheck
is able to source all of these files without needing the extra
directives:
v0.7.2 - 2021-04-19
Changed
* SC1090: A leading $x/ or $(x)/ is now treated as ./ when locating files
Remove them to avoid future copy pasting and confusion that they are
required. Because the paths weren't actually followed, they didn't have
to be accurate and accepted any string to silence the warning.
Signed-off-by: James Clark <james.clark@linaro.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The kernel renamed the OMR data attribute from offcore_rsp to
offmodule_rsp to avoid confusion and keep the naming consistent.
So update the perf jevents msrmap accordingly.
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
perf record enables buildid_all for AUX trace because buildid-list does
not decode AUX data to identify hit DSOs. Historically those build IDs
were available in HEADER_BUILD_ID, and buildid-list disabled hit
filtering when HEADER_AUXTRACE was present.
Build IDs are now carried by MMAP2 records by default and the build-ID
header is omitted. perf_session__list_build_ids() forces with_hits when
the header is absent so that it processes the event stream. That also
filters the result to DSOs referenced by ordinary samples. AUX data has
no such samples unless the trace is decoded, so every DSO is dropped and
perf archive reports that no build IDs were found.
Process the event stream whenever the build-ID header is absent,
allowing MMAP2 build IDs to be read, but do not enable hit filtering for
AUX data, this ensures that all build-IDs are included for AUX data.
Fixes: 6bd89ae7d1 ("perf record: Make sure to update build-ID cache")
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Codex:GPT-5.6-Sol
Signed-off-by: James Clark <james.clark@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
On s390 the kernel uses s390 back chain instead of frame pointers for
stack tracing of user space since v6.7 commit aa44433ac4 ("s390: add
USER_STACKTRACE support"). This is because frame pointers on s390
cannot be used for stack tracing. [1]
This requires user space to maintain a s390 back chain. For instance
user space to be built with compiler option '-mbackchain' (instead of
'-fno-omit-frame-pointer' used on other architectures, which should
better not be used on s390 [1]). Only few distributions and users build
user space with '-mbackchain'. Therefore '--call-graph fp' may in
practice not produce the expected results.
Commit ca76fb67eb ("perf evlist: Improve default event for s390")
changed the default '-g' option to 'dwarf' on s390 and added a warning
for s390 that wrongly claimed that "Framepointer unwinding lacks kernel
support". This warning resulted from a misinterpretation of comments
in s390 cpumsf_pmu_event_init().
The restriction in cpumsf_pmu_event_init() applies to callchain sampling
with the s390 CPU Measurement Sampling Facility (CPUMSF) hardware PMU.
CPUMSF events, such as 'cycles', do not support callchain sampling.
This is independent of whether perf uses the 'fp' or 'dwarf' call-graph
mode. The CPUMSF PMU provides samples collected asynchronously, making
it impossible to associate a callchain to the historic IPs. Therefore
callchains can only be used with software events on s390.
Remove the incorrect warning. The kernel supports the 'fp' call-graph
mode on s390 by walking the back chain. Do not replace it with a
hint to use 'dwarf' when the resulting callchain is incomplete. Such a
suggestion could imply that 'fp' is inherently inferior. The same
general limitation exists on other architectures when user space is not
built with frame pointers (i.e. '-fno-omit-frame-pointers').
Instead, warn on s390 when callchain sampling is requested with an event
provided by the CPUMCF or CPUMSF hardware PMUs, because that combination
is not supported.
Update the perf record documentation to state that 'dwarf' is the
default call-graph mode on s390 and that 'fp' uses back chain instead
of frame pointers on s390.
Note that '--call-graph fp' may also be useful for other applications,
such as OpenJDK maintaining a s390 back chain (does not require JVM
option '-XX:+PreserveFramePointer' on s390):
$ perf record --call-graph fp ... -- \
java -XX:+UnlockDiagnosticVMOptions -XX:+DumpPerfMapAtExit ...
[1]: s390: Stack tracing using Frame Pointer, Back Chain, and SFrame,
https://conf.gnu-tools-cauldron.org/opo25/talk/Y3CVHY/
Fixes: ca76fb67eb ("perf evlist: Improve default event for s390")
Reviewed-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>