diff options
Diffstat (limited to 'tools/perf/tests')
| -rw-r--r-- | tools/perf/tests/builtin-test.c | 8 | ||||
| -rw-r--r-- | tools/perf/tests/dwarf-unwind.c | 144 | ||||
| -rw-r--r-- | tools/perf/tests/hists_link.c | 1 | ||||
| -rw-r--r-- | tools/perf/tests/make | 25 | ||||
| -rw-r--r-- | tools/perf/tests/parse-events.c | 2 | ||||
| -rw-r--r-- | tools/perf/tests/sample-parsing.c | 17 | ||||
| -rw-r--r-- | tools/perf/tests/tests.h | 9 |
7 files changed, 185 insertions, 21 deletions
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 1e67437fb4ca..b11bf8a08430 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c | |||
| @@ -115,6 +115,14 @@ static struct test { | |||
| 115 | .desc = "Test parsing with no sample_id_all bit set", | 115 | .desc = "Test parsing with no sample_id_all bit set", |
| 116 | .func = test__parse_no_sample_id_all, | 116 | .func = test__parse_no_sample_id_all, |
| 117 | }, | 117 | }, |
| 118 | #if defined(__x86_64__) || defined(__i386__) | ||
| 119 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | ||
| 120 | { | ||
| 121 | .desc = "Test dwarf unwind", | ||
| 122 | .func = test__dwarf_unwind, | ||
| 123 | }, | ||
| 124 | #endif | ||
| 125 | #endif | ||
| 118 | { | 126 | { |
| 119 | .func = NULL, | 127 | .func = NULL, |
| 120 | }, | 128 | }, |
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c new file mode 100644 index 000000000000..c059ee81c038 --- /dev/null +++ b/tools/perf/tests/dwarf-unwind.c | |||
| @@ -0,0 +1,144 @@ | |||
| 1 | #include <linux/compiler.h> | ||
| 2 | #include <sys/types.h> | ||
| 3 | #include <unistd.h> | ||
| 4 | #include "tests.h" | ||
| 5 | #include "debug.h" | ||
| 6 | #include "machine.h" | ||
| 7 | #include "event.h" | ||
| 8 | #include "unwind.h" | ||
| 9 | #include "perf_regs.h" | ||
| 10 | #include "map.h" | ||
| 11 | #include "thread.h" | ||
| 12 | |||
| 13 | static int mmap_handler(struct perf_tool *tool __maybe_unused, | ||
| 14 | union perf_event *event, | ||
| 15 | struct perf_sample *sample __maybe_unused, | ||
| 16 | struct machine *machine) | ||
| 17 | { | ||
| 18 | return machine__process_mmap_event(machine, event, NULL); | ||
| 19 | } | ||
| 20 | |||
| 21 | static int init_live_machine(struct machine *machine) | ||
| 22 | { | ||
| 23 | union perf_event event; | ||
| 24 | pid_t pid = getpid(); | ||
| 25 | |||
| 26 | return perf_event__synthesize_mmap_events(NULL, &event, pid, pid, | ||
| 27 | mmap_handler, machine, true); | ||
| 28 | } | ||
| 29 | |||
| 30 | #define MAX_STACK 6 | ||
| 31 | |||
| 32 | static int unwind_entry(struct unwind_entry *entry, void *arg) | ||
| 33 | { | ||
| 34 | unsigned long *cnt = (unsigned long *) arg; | ||
| 35 | char *symbol = entry->sym ? entry->sym->name : NULL; | ||
| 36 | static const char *funcs[MAX_STACK] = { | ||
| 37 | "test__arch_unwind_sample", | ||
| 38 | "unwind_thread", | ||
| 39 | "krava_3", | ||
| 40 | "krava_2", | ||
| 41 | "krava_1", | ||
| 42 | "test__dwarf_unwind" | ||
| 43 | }; | ||
| 44 | |||
| 45 | if (*cnt >= MAX_STACK) { | ||
| 46 | pr_debug("failed: crossed the max stack value %d\n", MAX_STACK); | ||
| 47 | return -1; | ||
| 48 | } | ||
| 49 | |||
| 50 | if (!symbol) { | ||
| 51 | pr_debug("failed: got unresolved address 0x%" PRIx64 "\n", | ||
| 52 | entry->ip); | ||
| 53 | return -1; | ||
| 54 | } | ||
| 55 | |||
| 56 | pr_debug("got: %s 0x%" PRIx64 "\n", symbol, entry->ip); | ||
| 57 | return strcmp((const char *) symbol, funcs[(*cnt)++]); | ||
| 58 | } | ||
| 59 | |||
| 60 | __attribute__ ((noinline)) | ||
| 61 | static int unwind_thread(struct thread *thread, struct machine *machine) | ||
| 62 | { | ||
| 63 | struct perf_sample sample; | ||
| 64 | unsigned long cnt = 0; | ||
| 65 | int err = -1; | ||
| 66 | |||
| 67 | memset(&sample, 0, sizeof(sample)); | ||
| 68 | |||
| 69 | if (test__arch_unwind_sample(&sample, thread)) { | ||
| 70 | pr_debug("failed to get unwind sample\n"); | ||
| 71 | goto out; | ||
| 72 | } | ||
| 73 | |||
| 74 | err = unwind__get_entries(unwind_entry, &cnt, machine, thread, | ||
| 75 | &sample, MAX_STACK); | ||
| 76 | if (err) | ||
| 77 | pr_debug("unwind failed\n"); | ||
| 78 | else if (cnt != MAX_STACK) { | ||
| 79 | pr_debug("got wrong number of stack entries %lu != %d\n", | ||
| 80 | cnt, MAX_STACK); | ||
| 81 | err = -1; | ||
| 82 | } | ||
| 83 | |||
| 84 | out: | ||
| 85 | free(sample.user_stack.data); | ||
| 86 | free(sample.user_regs.regs); | ||
| 87 | return err; | ||
| 88 | } | ||
| 89 | |||
| 90 | __attribute__ ((noinline)) | ||
| 91 | static int krava_3(struct thread *thread, struct machine *machine) | ||
| 92 | { | ||
| 93 | return unwind_thread(thread, machine); | ||
| 94 | } | ||
| 95 | |||
| 96 | __attribute__ ((noinline)) | ||
| 97 | static int krava_2(struct thread *thread, struct machine *machine) | ||
| 98 | { | ||
| 99 | return krava_3(thread, machine); | ||
| 100 | } | ||
| 101 | |||
| 102 | __attribute__ ((noinline)) | ||
| 103 | static int krava_1(struct thread *thread, struct machine *machine) | ||
| 104 | { | ||
| 105 | return krava_2(thread, machine); | ||
| 106 | } | ||
| 107 | |||
| 108 | int test__dwarf_unwind(void) | ||
| 109 | { | ||
| 110 | struct machines machines; | ||
| 111 | struct machine *machine; | ||
| 112 | struct thread *thread; | ||
| 113 | int err = -1; | ||
| 114 | |||
| 115 | machines__init(&machines); | ||
| 116 | |||
| 117 | machine = machines__find(&machines, HOST_KERNEL_ID); | ||
| 118 | if (!machine) { | ||
| 119 | pr_err("Could not get machine\n"); | ||
| 120 | return -1; | ||
| 121 | } | ||
| 122 | |||
| 123 | if (init_live_machine(machine)) { | ||
| 124 | pr_err("Could not init machine\n"); | ||
| 125 | goto out; | ||
| 126 | } | ||
| 127 | |||
| 128 | if (verbose > 1) | ||
| 129 | machine__fprintf(machine, stderr); | ||
| 130 | |||
| 131 | thread = machine__find_thread(machine, getpid(), getpid()); | ||
| 132 | if (!thread) { | ||
| 133 | pr_err("Could not get thread\n"); | ||
| 134 | goto out; | ||
| 135 | } | ||
| 136 | |||
| 137 | err = krava_1(thread, machine); | ||
| 138 | |||
| 139 | out: | ||
| 140 | machine__delete_threads(machine); | ||
| 141 | machine__exit(machine); | ||
| 142 | machines__exit(&machines); | ||
| 143 | return err; | ||
| 144 | } | ||
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 2b6519e0e36f..7ccbc7b6ae77 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c | |||
| @@ -101,6 +101,7 @@ static struct machine *setup_fake_machine(struct machines *machines) | |||
| 101 | .mmap = { | 101 | .mmap = { |
| 102 | .header = { .misc = PERF_RECORD_MISC_USER, }, | 102 | .header = { .misc = PERF_RECORD_MISC_USER, }, |
| 103 | .pid = fake_mmap_info[i].pid, | 103 | .pid = fake_mmap_info[i].pid, |
| 104 | .tid = fake_mmap_info[i].pid, | ||
| 104 | .start = fake_mmap_info[i].start, | 105 | .start = fake_mmap_info[i].start, |
| 105 | .len = 0x1000ULL, | 106 | .len = 0x1000ULL, |
| 106 | .pgoff = 0ULL, | 107 | .pgoff = 0ULL, |
diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 00544b8b644b..5daeae1cb4c0 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make | |||
| @@ -27,6 +27,7 @@ make_no_ui := NO_NEWT=1 NO_SLANG=1 NO_GTK2=1 | |||
| 27 | make_no_demangle := NO_DEMANGLE=1 | 27 | make_no_demangle := NO_DEMANGLE=1 |
| 28 | make_no_libelf := NO_LIBELF=1 | 28 | make_no_libelf := NO_LIBELF=1 |
| 29 | make_no_libunwind := NO_LIBUNWIND=1 | 29 | make_no_libunwind := NO_LIBUNWIND=1 |
| 30 | make_no_libdw_dwarf_unwind := NO_LIBDW_DWARF_UNWIND=1 | ||
| 30 | make_no_backtrace := NO_BACKTRACE=1 | 31 | make_no_backtrace := NO_BACKTRACE=1 |
| 31 | make_no_libnuma := NO_LIBNUMA=1 | 32 | make_no_libnuma := NO_LIBNUMA=1 |
| 32 | make_no_libaudit := NO_LIBAUDIT=1 | 33 | make_no_libaudit := NO_LIBAUDIT=1 |
| @@ -35,8 +36,9 @@ make_tags := tags | |||
| 35 | make_cscope := cscope | 36 | make_cscope := cscope |
| 36 | make_help := help | 37 | make_help := help |
| 37 | make_doc := doc | 38 | make_doc := doc |
| 38 | make_perf_o := perf.o | 39 | make_perf_o := perf.o |
| 39 | make_util_map_o := util/map.o | 40 | make_util_map_o := util/map.o |
| 41 | make_util_pmu_bison_o := util/pmu-bison.o | ||
| 40 | make_install := install | 42 | make_install := install |
| 41 | make_install_bin := install-bin | 43 | make_install_bin := install-bin |
| 42 | make_install_doc := install-doc | 44 | make_install_doc := install-doc |
| @@ -49,6 +51,7 @@ make_install_pdf := install-pdf | |||
| 49 | make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 | 51 | make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 |
| 50 | make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 | 52 | make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 |
| 51 | make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 | 53 | make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 |
| 54 | make_minimal += NO_LIBDW_DWARF_UNWIND=1 | ||
| 52 | 55 | ||
| 53 | # $(run) contains all available tests | 56 | # $(run) contains all available tests |
| 54 | run := make_pure | 57 | run := make_pure |
| @@ -65,6 +68,7 @@ run += make_no_ui | |||
| 65 | run += make_no_demangle | 68 | run += make_no_demangle |
| 66 | run += make_no_libelf | 69 | run += make_no_libelf |
| 67 | run += make_no_libunwind | 70 | run += make_no_libunwind |
| 71 | run += make_no_libdw_dwarf_unwind | ||
| 68 | run += make_no_backtrace | 72 | run += make_no_backtrace |
| 69 | run += make_no_libnuma | 73 | run += make_no_libnuma |
| 70 | run += make_no_libaudit | 74 | run += make_no_libaudit |
| @@ -73,6 +77,7 @@ run += make_help | |||
| 73 | run += make_doc | 77 | run += make_doc |
| 74 | run += make_perf_o | 78 | run += make_perf_o |
| 75 | run += make_util_map_o | 79 | run += make_util_map_o |
| 80 | run += make_util_pmu_bison_o | ||
| 76 | run += make_install | 81 | run += make_install |
| 77 | run += make_install_bin | 82 | run += make_install_bin |
| 78 | # FIXME 'install-*' commented out till they're fixed | 83 | # FIXME 'install-*' commented out till they're fixed |
| @@ -113,8 +118,9 @@ test_make_doc_O := $(test_ok) | |||
| 113 | 118 | ||
| 114 | test_make_python_perf_so := test -f $(PERF)/python/perf.so | 119 | test_make_python_perf_so := test -f $(PERF)/python/perf.so |
| 115 | 120 | ||
| 116 | test_make_perf_o := test -f $(PERF)/perf.o | 121 | test_make_perf_o := test -f $(PERF)/perf.o |
| 117 | test_make_util_map_o := test -f $(PERF)/util/map.o | 122 | test_make_util_map_o := test -f $(PERF)/util/map.o |
| 123 | test_make_util_pmu_bison_o := test -f $(PERF)/util/pmu-bison.o | ||
| 118 | 124 | ||
| 119 | define test_dest_files | 125 | define test_dest_files |
| 120 | for file in $(1); do \ | 126 | for file in $(1); do \ |
| @@ -167,13 +173,10 @@ test_make_install_info_O := $(test_ok) | |||
| 167 | test_make_install_pdf := $(test_ok) | 173 | test_make_install_pdf := $(test_ok) |
| 168 | test_make_install_pdf_O := $(test_ok) | 174 | test_make_install_pdf_O := $(test_ok) |
| 169 | 175 | ||
| 170 | # Kbuild tests only | 176 | test_make_python_perf_so_O := test -f $$TMP_O/python/perf.so |
| 171 | #test_make_python_perf_so_O := test -f $$TMP/tools/perf/python/perf.so | 177 | test_make_perf_o_O := test -f $$TMP_O/perf.o |
| 172 | #test_make_perf_o_O := test -f $$TMP/tools/perf/perf.o | 178 | test_make_util_map_o_O := test -f $$TMP_O/util/map.o |
| 173 | #test_make_util_map_o_O := test -f $$TMP/tools/perf/util/map.o | 179 | test_make_util_pmu_bison_o_O := test -f $$TMP_O/util/pmu-bison.o |
| 174 | |||
| 175 | test_make_perf_o_O := true | ||
| 176 | test_make_util_map_o_O := true | ||
| 177 | 180 | ||
| 178 | test_default = test -x $(PERF)/perf | 181 | test_default = test -x $(PERF)/perf |
| 179 | test = $(if $(test_$1),$(test_$1),$(test_default)) | 182 | test = $(if $(test_$1),$(test_$1),$(test_default)) |
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 4db0ae617d70..8605ff5572ae 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #include "parse-events.h" | 2 | #include "parse-events.h" |
| 3 | #include "evsel.h" | 3 | #include "evsel.h" |
| 4 | #include "evlist.h" | 4 | #include "evlist.h" |
| 5 | #include "fs.h" | 5 | #include <api/fs/fs.h> |
| 6 | #include <api/fs/debugfs.h> | 6 | #include <api/fs/debugfs.h> |
| 7 | #include "tests.h" | 7 | #include "tests.h" |
| 8 | #include <linux/hw_breakpoint.h> | 8 | #include <linux/hw_breakpoint.h> |
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index 1b677202638d..0014d3c8c21c 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c | |||
| @@ -22,8 +22,8 @@ | |||
| 22 | } while (0) | 22 | } while (0) |
| 23 | 23 | ||
| 24 | static bool samples_same(const struct perf_sample *s1, | 24 | static bool samples_same(const struct perf_sample *s1, |
| 25 | const struct perf_sample *s2, u64 type, u64 regs_user, | 25 | const struct perf_sample *s2, |
| 26 | u64 read_format) | 26 | u64 type, u64 read_format) |
| 27 | { | 27 | { |
| 28 | size_t i; | 28 | size_t i; |
| 29 | 29 | ||
| @@ -95,8 +95,9 @@ static bool samples_same(const struct perf_sample *s1, | |||
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | if (type & PERF_SAMPLE_REGS_USER) { | 97 | if (type & PERF_SAMPLE_REGS_USER) { |
| 98 | size_t sz = hweight_long(regs_user) * sizeof(u64); | 98 | size_t sz = hweight_long(s1->user_regs.mask) * sizeof(u64); |
| 99 | 99 | ||
| 100 | COMP(user_regs.mask); | ||
| 100 | COMP(user_regs.abi); | 101 | COMP(user_regs.abi); |
| 101 | if (s1->user_regs.abi && | 102 | if (s1->user_regs.abi && |
| 102 | (!s1->user_regs.regs || !s2->user_regs.regs || | 103 | (!s1->user_regs.regs || !s2->user_regs.regs || |
| @@ -174,6 +175,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) | |||
| 174 | .branch_stack = &branch_stack.branch_stack, | 175 | .branch_stack = &branch_stack.branch_stack, |
| 175 | .user_regs = { | 176 | .user_regs = { |
| 176 | .abi = PERF_SAMPLE_REGS_ABI_64, | 177 | .abi = PERF_SAMPLE_REGS_ABI_64, |
| 178 | .mask = sample_regs_user, | ||
| 177 | .regs = user_regs, | 179 | .regs = user_regs, |
| 178 | }, | 180 | }, |
| 179 | .user_stack = { | 181 | .user_stack = { |
| @@ -201,8 +203,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) | |||
| 201 | sample.read.one.id = 99; | 203 | sample.read.one.id = 99; |
| 202 | } | 204 | } |
| 203 | 205 | ||
| 204 | sz = perf_event__sample_event_size(&sample, sample_type, | 206 | sz = perf_event__sample_event_size(&sample, sample_type, read_format); |
| 205 | sample_regs_user, read_format); | ||
| 206 | bufsz = sz + 4096; /* Add a bit for overrun checking */ | 207 | bufsz = sz + 4096; /* Add a bit for overrun checking */ |
| 207 | event = malloc(bufsz); | 208 | event = malloc(bufsz); |
| 208 | if (!event) { | 209 | if (!event) { |
| @@ -215,8 +216,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) | |||
| 215 | event->header.misc = 0; | 216 | event->header.misc = 0; |
| 216 | event->header.size = sz; | 217 | event->header.size = sz; |
| 217 | 218 | ||
| 218 | err = perf_event__synthesize_sample(event, sample_type, | 219 | err = perf_event__synthesize_sample(event, sample_type, read_format, |
| 219 | sample_regs_user, read_format, | ||
| 220 | &sample, false); | 220 | &sample, false); |
| 221 | if (err) { | 221 | if (err) { |
| 222 | pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", | 222 | pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", |
| @@ -244,8 +244,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) | |||
| 244 | goto out_free; | 244 | goto out_free; |
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | if (!samples_same(&sample, &sample_out, sample_type, | 247 | if (!samples_same(&sample, &sample_out, sample_type, read_format)) { |
| 248 | sample_regs_user, read_format)) { | ||
| 249 | pr_debug("parsing failed for sample_type %#"PRIx64"\n", | 248 | pr_debug("parsing failed for sample_type %#"PRIx64"\n", |
| 250 | sample_type); | 249 | sample_type); |
| 251 | goto out_free; | 250 | goto out_free; |
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index e0ac713857ba..a24795ca002d 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h | |||
| @@ -40,5 +40,14 @@ int test__code_reading(void); | |||
| 40 | int test__sample_parsing(void); | 40 | int test__sample_parsing(void); |
| 41 | int test__keep_tracking(void); | 41 | int test__keep_tracking(void); |
| 42 | int test__parse_no_sample_id_all(void); | 42 | int test__parse_no_sample_id_all(void); |
| 43 | int test__dwarf_unwind(void); | ||
| 43 | 44 | ||
| 45 | #if defined(__x86_64__) || defined(__i386__) | ||
| 46 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | ||
| 47 | struct thread; | ||
| 48 | struct perf_sample; | ||
| 49 | int test__arch_unwind_sample(struct perf_sample *sample, | ||
| 50 | struct thread *thread); | ||
| 51 | #endif | ||
| 52 | #endif | ||
| 44 | #endif /* TESTS_H */ | 53 | #endif /* TESTS_H */ |
