summaryrefslogtreecommitdiff
path: root/tools/perf/tests
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-12 11:46:21 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-12 11:46:21 -0800
commitbca13ce4554ae9cf5083e5adf395ad2266cb571b (patch)
treede392199f8eecd9c1331e2bcff5b60d4f188a5db /tools/perf/tests
parent0719dbf5e1e802f1bcd0b8d8fc7639d5d1584d48 (diff)
parentb0c1ef52959582144bbea9a2b37db7f4c9e399f7 (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "This update is pretty big and almost exclusively includes tooling changes, because v4.9's LTS status forced to completion most of the pending kernel side hardware enablement work and because we tried to freeze core perf work a bit to give a time window for the fuzzing efforts. The diff is large mostly due to the JSON hardware event tables added for Intel and Power8 CPUs. This was a popular feature request from people working close to hardware and from the HPC community. Tree size is big because this added the CPU event tables for over a decade of Intel CPUs. Future changes for a CPU vendor alrady support should be much smaller, as events for new models are added. The new events are listed in 'perf list', for the CPU model the tool is running on. If you find an interesting event it can be used as-is: $ perf stat -a -e l2_lines_out.pf_clean sleep 1 Performance counter stats for 'system wide': 7,860,403 l2_lines_out.pf_clean 1.000624918 seconds time elapsed The event lists can be searched the usual 'perf list' fashion for (case insensitive) substrings as well: $ perf list l2_lines_out List of pre-defined events (to be used in -e): cache: l2_lines_out.demand_clean [Clean L2 cache lines evicted by demand] l2_lines_out.demand_dirty [Dirty L2 cache lines evicted by demand] l2_lines_out.dirty_all [Dirty L2 cache lines filling the L2] l2_lines_out.pf_clean [Clean L2 cache lines evicted by L2 prefetch] l2_lines_out.pf_dirty [Dirty L2 cache lines evicted by L2 prefetch] etc. There's a few high level categories as well that can be listed: 'cache', 'floating point', 'frontend', 'memory', 'pipeline', 'virtual memory'. Existing generic events and workflows should work as-is. The only kernel side change is a late breaking fix for an older regression, related to Intel BTS, LBR and PT feature interaction. On the tooling side there are three new tools / major features: - The new 'perf c2c' tool provides means for Shared Data C2C/HITM analysis. This allows you to track down cacheline contention. The tool is based on x86's load latency and precise store facility events provided by Intel CPUs. It was tested by Joe Mario and has proven to be useful, finding some cacheline contentions. Joe also wrote a blog about c2c tool with examples: https://joemario.github.io/blog/2016/09/01/c2c-blog/ excerpt of the content on this site: At a high level, “perf c2c” will show you: * The cachelines where false sharing was detected. * The readers and writers to those cachelines, and the offsets where those accesses occurred. * The pid, tid, instruction addr, function name, binary object name for those readers and writers. * The source file and line number for each reader and writer. * The average load latency for the loads to those cachelines. * Which numa nodes the samples a cacheline came from and which CPUs were involved. Using perf c2c is similar to using the Linux perf tool today. First collect data with “perf c2c record”, then generate a report output with “perf c2c report” There one finds extensive details on using the tool, with tips on reducing the volume of samples while still capturing enough to do its job. (Dick Fowles, Joe Mario, Don Zickus, Jiri Olsa) - The new 'perf sched timehist' tool provides tailored analysis of scheduling events. Example usage: perf sched record -- sleep 1 perf sched timehist By default it shows the individual schedule events, including the wait time (time between sched-out and next sched-in events for the task), the task scheduling delay (time between wakeup and actually running) and run time for the task: time cpu task name wait time sch delay run time [tid/pid] (msec) (msec) (msec) -------- ------ ---------------- --------- --------- -------- 1.874569 [0011] gcc[31949] 0.014 0.000 1.148 1.874591 [0010] gcc[31951] 0.000 0.000 0.024 1.874603 [0010] migration/10[59] 3.350 0.004 0.011 1.874604 [0011] <idle> 1.148 0.000 0.035 1.874723 [0005] <idle> 0.016 0.000 1.383 1.874746 [0005] gcc[31949] 0.153 0.078 0.022 ... Times are in msec.usec. (David Ahern, Namhyung Kim) - Add CPU vendor hardware event tables: Add JSON files with vendor event naming for Intel and Power8 processors, allowing users of tools like oprofile to keep using the event names they are used to, as well as people reading vendor documentation, where such naming is used. (Andi Kleen, Sukadev Bhattiprolu) You should see all the new events with 'perf list' and you should be able to search them, for example 'perf list miss' will list all the myriads of miss events. Other tooling features added were: - Cross-arch annotation support: o Improve ARM support in the annotation code, affecting 'perf annotate', 'perf report' and live annotation in 'perf top' (Kim Phillips) o Initial support for PowerPC in the annotation code (Ravi Bangoria) o Support AArch64 in the 'annotate' code, native/local and cross-arch/remote (Kim Phillips) - Allow considering just events in a given time interval, via the '--time start.s.ms,end.s.ms' command line, added to 'perf kmem', 'perf report', 'perf sched timehist' and 'perf script' (David Ahern) - Add option to stop printing a callchain at one of a given group of symbol names (David Ahern) - Track memory freed in 'perf kmem stat' (David Ahern) - Allow querying and setting .perfconfig variables (Taeung Song) - Show branch information in callchains (predicted, TSX aborts, loop iteractions, etc) (Jin Yao) - Dynamicly change verbosity level by pressing 'V' in the 'perf top/report' hists TUI browser (Alexis Berlemont) - Implement 'perf trace --delay' in the same fashion as in 'perf record --delay', to skip sampling workload initialization events (Alexis Berlemont) - Make vendor named events case insensitive in 'perf list', i.e. 'perf list LONGEST_LAT' works just the same as 'perf list longest_lat' (Andi Kleen) - Add unwinding support for jitdump (Stefano Sanfilippo) Tooling infrastructure changes: - Support linking perf with clang and LLVM libraries, initially statically, but this limitation will be lifted and shared libraries, when available, will be preferred to the static build, that should, as with other features, be enabled explicitly (Wang Nan) - Add initial support (and perf test entry) for tooling hooks, starting with 'record_start' and 'record_end', that will have as its initial user the eBPF infrastructure, where perf_ prefixed functions will be JITed and run when such hooks are called (Wang Nan) - Implement assorted libbpf improvements (Wang Nan)" ... and lots of other changes, features, cleanups and refactorings I did not list, see the shortlog and the git log for details" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (220 commits) perf/x86: Fix exclusion of BTS and LBR for Goldmont perf tools: Explicitly document that --children is enabled by default perf sched timehist: Cleanup idle_max_cpu handling perf sched timehist: Handle zero sample->tid properly perf callchain: Introduce callchain_cursor__copy() perf sched: Cleanup option processing perf sched timehist: Improve error message when analyzing wrong file perf tools: Move perf build related variables under non fixdep leg perf tools: Force fixdep compilation at the start of the build perf tools: Move PERF-VERSION-FILE target into rules area perf build: Check LLVM version in feature check perf annotate: Show raw form for jump instruction with indirect target perf tools: Add non config targets perf tools: Cleanup build directory before each test perf tools: Move python/perf.so target into rules area perf tools: Move install-gtk target into rules area tools build: Move tabs to spaces where suitable tools build: Make the .cmd file more readable perf clang: Compile BPF script using builtin clang support perf clang: Support compile IR to BPF object and add testcase ...
Diffstat (limited to 'tools/perf/tests')
-rw-r--r--tools/perf/tests/Build2
-rw-r--r--tools/perf/tests/backward-ring-buffer.c2
-rw-r--r--tools/perf/tests/bpf.c8
-rw-r--r--tools/perf/tests/builtin-test.c105
-rw-r--r--tools/perf/tests/clang.c46
-rw-r--r--tools/perf/tests/llvm.c8
-rw-r--r--tools/perf/tests/llvm.h7
-rw-r--r--tools/perf/tests/make6
-rw-r--r--tools/perf/tests/perf-hooks.c48
-rw-r--r--tools/perf/tests/tests.h4
10 files changed, 179 insertions, 57 deletions
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 8a4ce492f7b2..6676c2dd6dcb 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -42,6 +42,8 @@ perf-y += backward-ring-buffer.o
perf-y += sdt.o
perf-y += is_printable_array.o
perf-y += bitmap.o
+perf-y += perf-hooks.o
+perf-y += clang.o
$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
$(call rule_mkdir)
diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c
index e6d1816e431a..42e892b1e979 100644
--- a/tools/perf/tests/backward-ring-buffer.c
+++ b/tools/perf/tests/backward-ring-buffer.c
@@ -97,7 +97,7 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
evlist = perf_evlist__new();
if (!evlist) {
- pr_debug("No enough memory to create evlist\n");
+ pr_debug("Not enough memory to create evlist\n");
return TEST_FAIL;
}
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
index 2673e86ed50f..92343f43e44a 100644
--- a/tools/perf/tests/bpf.c
+++ b/tools/perf/tests/bpf.c
@@ -57,7 +57,7 @@ static struct {
} bpf_testcase_table[] = {
{
LLVM_TESTCASE_BASE,
- "Test basic BPF filtering",
+ "Basic BPF filtering",
"[basic_bpf_test]",
"fix 'perf test LLVM' first",
"load bpf object failed",
@@ -67,7 +67,7 @@ static struct {
#ifdef HAVE_BPF_PROLOGUE
{
LLVM_TESTCASE_BPF_PROLOGUE,
- "Test BPF prologue generation",
+ "BPF prologue generation",
"[bpf_prologue_test]",
"fix kbuild first",
"check your vmlinux setting?",
@@ -77,7 +77,7 @@ static struct {
#endif
{
LLVM_TESTCASE_BPF_RELOCATION,
- "Test BPF relocation checker",
+ "BPF relocation checker",
"[bpf_relocation_test]",
"fix 'perf test LLVM' first",
"libbpf error when dealing with relocation",
@@ -125,7 +125,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void),
/* Instead of perf_evlist__new_default, don't add default events */
evlist = perf_evlist__new();
if (!evlist) {
- pr_debug("No enough memory to create evlist\n");
+ pr_debug("Not enough memory to create evlist\n");
return TEST_FAIL;
}
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 778668a2a966..23605202d4a1 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -28,119 +28,119 @@ static struct test generic_tests[] = {
.func = test__vmlinux_matches_kallsyms,
},
{
- .desc = "detect openat syscall event",
+ .desc = "Detect openat syscall event",
.func = test__openat_syscall_event,
},
{
- .desc = "detect openat syscall event on all cpus",
+ .desc = "Detect openat syscall event on all cpus",
.func = test__openat_syscall_event_on_all_cpus,
},
{
- .desc = "read samples using the mmap interface",
+ .desc = "Read samples using the mmap interface",
.func = test__basic_mmap,
},
{
- .desc = "parse events tests",
+ .desc = "Parse event definition strings",
.func = test__parse_events,
},
{
- .desc = "Validate PERF_RECORD_* events & perf_sample fields",
+ .desc = "PERF_RECORD_* events & perf_sample fields",
.func = test__PERF_RECORD,
},
{
- .desc = "Test perf pmu format parsing",
+ .desc = "Parse perf pmu format",
.func = test__pmu,
},
{
- .desc = "Test dso data read",
+ .desc = "DSO data read",
.func = test__dso_data,
},
{
- .desc = "Test dso data cache",
+ .desc = "DSO data cache",
.func = test__dso_data_cache,
},
{
- .desc = "Test dso data reopen",
+ .desc = "DSO data reopen",
.func = test__dso_data_reopen,
},
{
- .desc = "roundtrip evsel->name check",
+ .desc = "Roundtrip evsel->name",
.func = test__perf_evsel__roundtrip_name_test,
},
{
- .desc = "Check parsing of sched tracepoints fields",
+ .desc = "Parse sched tracepoints fields",
.func = test__perf_evsel__tp_sched_test,
},
{
- .desc = "Generate and check syscalls:sys_enter_openat event fields",
+ .desc = "syscalls:sys_enter_openat event fields",
.func = test__syscall_openat_tp_fields,
},
{
- .desc = "struct perf_event_attr setup",
+ .desc = "Setup struct perf_event_attr",
.func = test__attr,
},
{
- .desc = "Test matching and linking multiple hists",
+ .desc = "Match and link multiple hists",
.func = test__hists_link,
},
{
- .desc = "Try 'import perf' in python, checking link problems",
+ .desc = "'import perf' in python",
.func = test__python_use,
},
{
- .desc = "Test breakpoint overflow signal handler",
+ .desc = "Breakpoint overflow signal handler",
.func = test__bp_signal,
},
{
- .desc = "Test breakpoint overflow sampling",
+ .desc = "Breakpoint overflow sampling",
.func = test__bp_signal_overflow,
},
{
- .desc = "Test number of exit event of a simple workload",
+ .desc = "Number of exit events of a simple workload",
.func = test__task_exit,
},
{
- .desc = "Test software clock events have valid period values",
+ .desc = "Software clock events period values",
.func = test__sw_clock_freq,
},
{
- .desc = "Test object code reading",
+ .desc = "Object code reading",
.func = test__code_reading,
},
{
- .desc = "Test sample parsing",
+ .desc = "Sample parsing",
.func = test__sample_parsing,
},
{
- .desc = "Test using a dummy software event to keep tracking",
+ .desc = "Use a dummy software event to keep tracking",
.func = test__keep_tracking,
},
{
- .desc = "Test parsing with no sample_id_all bit set",
+ .desc = "Parse with no sample_id_all bit set",
.func = test__parse_no_sample_id_all,
},
{
- .desc = "Test filtering hist entries",
+ .desc = "Filter hist entries",
.func = test__hists_filter,
},
{
- .desc = "Test mmap thread lookup",
+ .desc = "Lookup mmap thread",
.func = test__mmap_thread_lookup,
},
{
- .desc = "Test thread mg sharing",
+ .desc = "Share thread mg",
.func = test__thread_mg_share,
},
{
- .desc = "Test output sorting of hist entries",
+ .desc = "Sort output of hist entries",
.func = test__hists_output,
},
{
- .desc = "Test cumulation of child hist entries",
+ .desc = "Cumulate child hist entries",
.func = test__hists_cumulate,
},
{
- .desc = "Test tracking with sched_switch",
+ .desc = "Track with sched_switch",
.func = test__switch_tracking,
},
{
@@ -152,15 +152,15 @@ static struct test generic_tests[] = {
.func = test__fdarray__add,
},
{
- .desc = "Test kmod_path__parse function",
+ .desc = "kmod_path__parse",
.func = test__kmod_path__parse,
},
{
- .desc = "Test thread map",
+ .desc = "Thread map",
.func = test__thread_map,
},
{
- .desc = "Test LLVM searching and compiling",
+ .desc = "LLVM search and compile",
.func = test__llvm,
.subtest = {
.skip_if_fail = true,
@@ -169,11 +169,11 @@ static struct test generic_tests[] = {
},
},
{
- .desc = "Test topology in session",
+ .desc = "Session topology",
.func = test_session_topology,
},
{
- .desc = "Test BPF filter",
+ .desc = "BPF filter",
.func = test__bpf,
.subtest = {
.skip_if_fail = true,
@@ -182,54 +182,67 @@ static struct test generic_tests[] = {
},
},
{
- .desc = "Test thread map synthesize",
+ .desc = "Synthesize thread map",
.func = test__thread_map_synthesize,
},
{
- .desc = "Test cpu map synthesize",
+ .desc = "Synthesize cpu map",
.func = test__cpu_map_synthesize,
},
{
- .desc = "Test stat config synthesize",
+ .desc = "Synthesize stat config",
.func = test__synthesize_stat_config,
},
{
- .desc = "Test stat synthesize",
+ .desc = "Synthesize stat",
.func = test__synthesize_stat,
},
{
- .desc = "Test stat round synthesize",
+ .desc = "Synthesize stat round",
.func = test__synthesize_stat_round,
},
{
- .desc = "Test attr update synthesize",
+ .desc = "Synthesize attr update",
.func = test__event_update,
},
{
- .desc = "Test events times",
+ .desc = "Event times",
.func = test__event_times,
},
{
- .desc = "Test backward reading from ring buffer",
+ .desc = "Read backward ring buffer",
.func = test__backward_ring_buffer,
},
{
- .desc = "Test cpu map print",
+ .desc = "Print cpu map",
.func = test__cpu_map_print,
},
{
- .desc = "Test SDT event probing",
+ .desc = "Probe SDT events",
.func = test__sdt_event,
},
{
- .desc = "Test is_printable_array function",
+ .desc = "is_printable_array",
.func = test__is_printable_array,
},
{
- .desc = "Test bitmap print",
+ .desc = "Print bitmap",
.func = test__bitmap_print,
},
{
+ .desc = "perf hooks",
+ .func = test__perf_hooks,
+ },
+ {
+ .desc = "builtin clang support",
+ .func = test__clang,
+ .subtest = {
+ .skip_if_fail = true,
+ .get_nr = test__clang_subtest_get_nr,
+ .get_desc = test__clang_subtest_get_desc,
+ }
+ },
+ {
.func = NULL,
},
};
diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c
new file mode 100644
index 000000000000..f853e242a86c
--- /dev/null
+++ b/tools/perf/tests/clang.c
@@ -0,0 +1,46 @@
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+#include "c++/clang-c.h"
+
+static struct {
+ int (*func)(void);
+ const char *desc;
+} clang_testcase_table[] = {
+#ifdef HAVE_LIBCLANGLLVM_SUPPORT
+ {
+ .func = test__clang_to_IR,
+ .desc = "builtin clang compile C source to IR",
+ },
+ {
+ .func = test__clang_to_obj,
+ .desc = "builtin clang compile C source to ELF object",
+ },
+#endif
+};
+
+int test__clang_subtest_get_nr(void)
+{
+ return (int)ARRAY_SIZE(clang_testcase_table);
+}
+
+const char *test__clang_subtest_get_desc(int i)
+{
+ if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table))
+ return NULL;
+ return clang_testcase_table[i].desc;
+}
+
+#ifndef HAVE_LIBCLANGLLVM_SUPPORT
+int test__clang(int i __maybe_unused)
+{
+ return TEST_SKIP;
+}
+#else
+int test__clang(int i)
+{
+ if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table))
+ return TEST_FAIL;
+ return clang_testcase_table[i].func();
+}
+#endif
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index b798a4bfd238..02a33ebcd992 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -34,19 +34,19 @@ static struct {
} bpf_source_table[__LLVM_TESTCASE_MAX] = {
[LLVM_TESTCASE_BASE] = {
.source = test_llvm__bpf_base_prog,
- .desc = "Basic BPF llvm compiling test",
+ .desc = "Basic BPF llvm compile",
},
[LLVM_TESTCASE_KBUILD] = {
.source = test_llvm__bpf_test_kbuild_prog,
- .desc = "Test kbuild searching",
+ .desc = "kbuild searching",
},
[LLVM_TESTCASE_BPF_PROLOGUE] = {
.source = test_llvm__bpf_test_prologue_prog,
- .desc = "Compile source for BPF prologue generation test",
+ .desc = "Compile source for BPF prologue generation",
},
[LLVM_TESTCASE_BPF_RELOCATION] = {
.source = test_llvm__bpf_test_relocation,
- .desc = "Compile source for BPF relocation test",
+ .desc = "Compile source for BPF relocation",
.should_load_fail = true,
},
};
diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h
index 0eaa604be99d..b83571758d83 100644
--- a/tools/perf/tests/llvm.h
+++ b/tools/perf/tests/llvm.h
@@ -1,6 +1,10 @@
#ifndef PERF_TEST_LLVM_H
#define PERF_TEST_LLVM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <stddef.h> /* for size_t */
#include <stdbool.h> /* for bool */
@@ -20,4 +24,7 @@ enum test_llvm__testcase {
int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz,
enum test_llvm__testcase index, bool force,
bool *should_load_fail);
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 143f4d549769..0784748f1670 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -83,6 +83,7 @@ make_no_libbpf := NO_LIBBPF=1
make_no_libcrypto := NO_LIBCRYPTO=1
make_with_babeltrace:= LIBBABELTRACE=1
make_no_sdt := NO_SDT=1
+make_with_clangllvm := LIBCLANGLLVM=1
make_tags := tags
make_cscope := cscope
make_help := help
@@ -106,7 +107,7 @@ make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
-make_minimal += NO_LIBCRYPTO=1 NO_SDT=1
+make_minimal += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1
# $(run) contains all available tests
run := make_pure
@@ -139,6 +140,7 @@ run += make_no_libbionic
run += make_no_auxtrace
run += make_no_libbpf
run += make_with_babeltrace
+run += make_with_clangllvm
run += make_help
run += make_doc
run += make_perf_o
@@ -278,7 +280,7 @@ endif
MAKEFLAGS := --no-print-directory
-clean := @(cd $(PERF); $(MAKE_F) -s $(O_OPT) clean >/dev/null)
+clean := @(cd $(PERF); $(MAKE_F) -s $(O_OPT) clean >/dev/null && $(MAKE) -s $(O_OPT) -C ../build clean >/dev/null)
$(run):
$(call clean)
diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c
new file mode 100644
index 000000000000..665ecc19671c
--- /dev/null
+++ b/tools/perf/tests/perf-hooks.c
@@ -0,0 +1,48 @@
+#include <signal.h>
+#include <stdlib.h>
+
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+#include "perf-hooks.h"
+
+static void sigsegv_handler(int sig __maybe_unused)
+{
+ pr_debug("SIGSEGV is observed as expected, try to recover.\n");
+ perf_hooks__recover();
+ signal(SIGSEGV, SIG_DFL);
+ raise(SIGSEGV);
+ exit(-1);
+}
+
+
+static void the_hook(void *_hook_flags)
+{
+ int *hook_flags = _hook_flags;
+ int *p = NULL;
+
+ *hook_flags = 1234;
+
+ /* Generate a segfault, test perf_hooks__recover */
+ *p = 0;
+}
+
+int test__perf_hooks(int subtest __maybe_unused)
+{
+ int hook_flags = 0;
+
+ signal(SIGSEGV, sigsegv_handler);
+ perf_hooks__set_hook("test", the_hook, &hook_flags);
+ perf_hooks__invoke_test();
+
+ /* hook is triggered? */
+ if (hook_flags != 1234) {
+ pr_debug("Setting failed: %d (%p)\n", hook_flags, &hook_flags);
+ return TEST_FAIL;
+ }
+
+ /* the buggy hook is removed? */
+ if (perf_hooks__get_hook("test"))
+ return TEST_FAIL;
+ return TEST_OK;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 7c196c585472..0d7b251305af 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -91,6 +91,10 @@ int test__cpu_map_print(int subtest);
int test__sdt_event(int subtest);
int test__is_printable_array(int subtest);
int test__bitmap_print(int subtest);
+int test__perf_hooks(int subtest);
+int test__clang(int subtest);
+const char *test__clang_subtest_get_desc(int subtest);
+int test__clang_subtest_get_nr(void);
#if defined(__arm__) || defined(__aarch64__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT