diff options
Diffstat (limited to 'tools/perf/tests')
30 files changed, 331 insertions, 81 deletions
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 66a28982547b..cb20ae1c0d35 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -39,6 +39,8 @@ perf-y += stat.o  perf-y += event_update.o  perf-y += event-times.o  perf-y += backward-ring-buffer.o +perf-y += sdt.o +perf-y += is_printable_array.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 d9ba991a9a30..615780cbfe1d 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -31,8 +31,8 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count,  	for (i = 0; i < evlist->nr_mmaps; i++) {  		union perf_event *event; -		perf_evlist__mmap_read_catchup(evlist, i); -		while ((event = perf_evlist__mmap_read_backward(evlist, i)) != NULL) { +		perf_mmap__read_catchup(&evlist->backward_mmap[i]); +		while ((event = perf_mmap__read_backward(&evlist->backward_mmap[i])) != NULL) {  			const u32 type = event->header.type;  			switch (type) { @@ -60,7 +60,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages,  	err = perf_evlist__mmap(evlist, mmap_pages, true);  	if (err < 0) {  		pr_debug("perf_evlist__mmap: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		return TEST_FAIL;  	} @@ -108,7 +108,11 @@ int test__backward_ring_buffer(int subtest __maybe_unused)  	}  	bzero(&parse_error, sizeof(parse_error)); -	err = parse_events(evlist, "syscalls:sys_enter_prctl", &parse_error); +	/* +	 * Set backward bit, ring buffer should be writing from end. Record +	 * it in aux evlist +	 */ +	err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", &parse_error);  	if (err) {  		pr_debug("Failed to parse tracepoint event, try use root\n");  		ret = TEST_SKIP; @@ -117,14 +121,10 @@ int test__backward_ring_buffer(int subtest __maybe_unused)  	perf_evlist__config(evlist, &opts, NULL); -	/* Set backward bit, ring buffer should be writing from end */ -	evlist__for_each(evlist, evsel) -		evsel->attr.write_backward = 1; -  	err = perf_evlist__open(evlist);  	if (err < 0) {  		pr_debug("perf_evlist__open: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} diff --git a/tools/perf/tests/bpf-script-example.c b/tools/perf/tests/bpf-script-example.c index 0ec9c2c03164..e53bc91fa260 100644 --- a/tools/perf/tests/bpf-script-example.c +++ b/tools/perf/tests/bpf-script-example.c @@ -31,8 +31,8 @@ struct bpf_map_def SEC("maps") flip_table = {  	.max_entries = 1,  }; -SEC("func=sys_epoll_pwait") -int bpf_func__sys_epoll_pwait(void *ctx) +SEC("func=sys_epoll_wait") +int bpf_func__sys_epoll_wait(void *ctx)  {  	int ind =0;  	int *flag = bpf_map_lookup_elem(&flip_table, &ind); diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index f31eed31c1a9..fc54064b9186 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -13,13 +13,13 @@  #ifdef HAVE_LIBBPF_SUPPORT -static int epoll_pwait_loop(void) +static int epoll_wait_loop(void)  {  	int i;  	/* Should fail NR_ITERS times */  	for (i = 0; i < NR_ITERS; i++) -		epoll_pwait(-(i + 1), NULL, 0, 0, NULL); +		epoll_wait(-(i + 1), NULL, 0, 0);  	return 0;  } @@ -61,7 +61,7 @@ static struct {  		"[basic_bpf_test]",  		"fix 'perf test LLVM' first",  		"load bpf object failed", -		&epoll_pwait_loop, +		&epoll_wait_loop,  		(NR_ITERS + 1) / 2,  	},  #ifdef HAVE_BPF_PROLOGUE @@ -143,14 +143,14 @@ static int do_test(struct bpf_object *obj, int (*func)(void),  	err = perf_evlist__open(evlist);  	if (err < 0) {  		pr_debug("perf_evlist__open: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	}  	err = perf_evlist__mmap(evlist, opts.mmap_pages, false);  	if (err < 0) {  		pr_debug("perf_evlist__mmap: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 0e95c20ecf6e..10eb30686c9c 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -14,6 +14,8 @@  #include <subcmd/parse-options.h>  #include "symbol.h" +static bool dont_fork; +  struct test __weak arch_tests[] = {  	{  		.func = NULL, @@ -212,6 +214,18 @@ static struct test generic_tests[] = {  		.func = test__backward_ring_buffer,  	},  	{ +		.desc = "Test cpu map print", +		.func = test__cpu_map_print, +	}, +	{ +		.desc = "Test SDT event probing", +		.func = test__sdt_event, +	}, +	{ +		.desc = "Test is_printable_array function", +		.func = test__is_printable_array, +	}, +	{  		.func = NULL,  	},  }; @@ -247,44 +261,51 @@ static bool perf_test__matches(struct test *test, int curr, int argc, const char  static int run_test(struct test *test, int subtest)  { -	int status, err = -1, child = fork(); +	int status, err = -1, child = dont_fork ? 0 : fork();  	char sbuf[STRERR_BUFSIZE];  	if (child < 0) {  		pr_err("failed to fork test: %s\n", -			strerror_r(errno, sbuf, sizeof(sbuf))); +			str_error_r(errno, sbuf, sizeof(sbuf)));  		return -1;  	}  	if (!child) { -		pr_debug("test child forked, pid %d\n", getpid()); -		if (!verbose) { -			int nullfd = open("/dev/null", O_WRONLY); -			if (nullfd >= 0) { -				close(STDERR_FILENO); -				close(STDOUT_FILENO); - -				dup2(nullfd, STDOUT_FILENO); -				dup2(STDOUT_FILENO, STDERR_FILENO); -				close(nullfd); +		if (!dont_fork) { +			pr_debug("test child forked, pid %d\n", getpid()); + +			if (!verbose) { +				int nullfd = open("/dev/null", O_WRONLY); + +				if (nullfd >= 0) { +					close(STDERR_FILENO); +					close(STDOUT_FILENO); + +					dup2(nullfd, STDOUT_FILENO); +					dup2(STDOUT_FILENO, STDERR_FILENO); +					close(nullfd); +				} +			} else { +				signal(SIGSEGV, sighandler_dump_stack); +				signal(SIGFPE, sighandler_dump_stack);  			} -		} else { -			signal(SIGSEGV, sighandler_dump_stack); -			signal(SIGFPE, sighandler_dump_stack);  		}  		err = test->func(subtest); -		exit(err); +		if (!dont_fork) +			exit(err);  	} -	wait(&status); +	if (!dont_fork) { +		wait(&status); -	if (WIFEXITED(status)) { -		err = (signed char)WEXITSTATUS(status); -		pr_debug("test child finished with %d\n", err); -	} else if (WIFSIGNALED(status)) { -		err = -1; -		pr_debug("test child interrupted\n"); +		if (WIFEXITED(status)) { +			err = (signed char)WEXITSTATUS(status); +			pr_debug("test child finished with %d\n", err); +		} else if (WIFSIGNALED(status)) { +			err = -1; +			pr_debug("test child interrupted\n"); +		}  	}  	return err; @@ -425,6 +446,8 @@ int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)  	OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),  	OPT_INCR('v', "verbose", &verbose,  		    "be more verbose (show symbol address, etc)"), +	OPT_BOOLEAN('F', "dont-fork", &dont_fork, +		    "Do not fork for testcase"),  	OPT_END()  	};  	const char * const test_subcommands[] = { "list", NULL }; diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 4cb6418a8ffc..f168a85992d0 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -1,5 +1,12 @@  #include "tests.h" +#include <stdio.h>  #include "cpumap.h" +#include "event.h" +#include <string.h> +#include <linux/bitops.h> +#include "debug.h" + +struct machine;  static int process_event_mask(struct perf_tool *tool __maybe_unused,  			 union perf_event *event, @@ -86,3 +93,27 @@ int test__cpu_map_synthesize(int subtest __maybe_unused)  	cpu_map__put(cpus);  	return 0;  } + +static int cpu_map_print(const char *str) +{ +	struct cpu_map *map = cpu_map__new(str); +	char buf[100]; + +	if (!map) +		return -1; + +	cpu_map__snprint(map, buf, sizeof(buf)); +	return !strcmp(buf, str); +} + +int test__cpu_map_print(int subtest __maybe_unused) +{ +	TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1")); +	TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5")); +	TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3,5,7,9,11,13,15,17,19,21-40")); +	TEST_ASSERT_VAL("failed to convert map", cpu_map_print("2-5")); +	TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37")); +	TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37")); +	TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1-10,12-20,22-30,32-40")); +	return 0; +} diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 8cf0d9e189a8..13725e09ba22 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -251,6 +251,9 @@ int test__dso_data_cache(int subtest __maybe_unused)  	long nr_end, nr = open_files_cnt();  	int dso_cnt, limit, i, fd; +	/* Rest the internal dso open counter limit. */ +	reset_fd_limit(); +  	memset(&machine, 0, sizeof(machine));  	/* set as system limit */ @@ -312,6 +315,9 @@ int test__dso_data_reopen(int subtest __maybe_unused)  #define dso_1 (dsos[1])  #define dso_2 (dsos[2]) +	/* Rest the internal dso open counter limit. */ +	reset_fd_limit(); +  	memset(&machine, 0, sizeof(machine));  	/* diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 95fb744f6628..19ef77bd6eb4 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -37,7 +37,7 @@ static int attach__enable_on_exec(struct perf_evlist *evlist)  	err = perf_evlist__open(evlist);  	if (err < 0) {  		pr_debug("perf_evlist__open: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		return err;  	} @@ -200,8 +200,7 @@ static int test_times(int (attach)(struct perf_evlist *),  		 count.ena, count.run);  out_err: -	if (evlist) -		perf_evlist__delete(evlist); +	perf_evlist__delete(evlist);  	return !err ? TEST_OK : TEST_FAIL;  } diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index 2de4a4f2c3ed..60926a1f6fd7 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -80,7 +80,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names)  	}  	err = 0; -	evlist__for_each(evlist, evsel) { +	evlist__for_each_entry(evlist, evsel) {  		if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {  			--err;  			pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]); diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c index c809463edbe5..a2b5ff9bf83d 100644 --- a/tools/perf/tests/fdarray.c +++ b/tools/perf/tests/fdarray.c @@ -1,4 +1,5 @@  #include <api/fd/array.h> +#include <poll.h>  #include "util/debug.h"  #include "tests/tests.h" @@ -36,7 +37,7 @@ int test__fdarray__filter(int subtest __maybe_unused)  	}  	fdarray__init_revents(fda, POLLIN); -	nr_fds = fdarray__filter(fda, POLLHUP, NULL); +	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);  	if (nr_fds != fda->nr_alloc) {  		pr_debug("\nfdarray__filter()=%d != %d shouldn't have filtered anything",  			 nr_fds, fda->nr_alloc); @@ -44,7 +45,7 @@ int test__fdarray__filter(int subtest __maybe_unused)  	}  	fdarray__init_revents(fda, POLLHUP); -	nr_fds = fdarray__filter(fda, POLLHUP, NULL); +	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);  	if (nr_fds != 0) {  		pr_debug("\nfdarray__filter()=%d != %d, should have filtered all fds",  			 nr_fds, fda->nr_alloc); @@ -57,7 +58,7 @@ int test__fdarray__filter(int subtest __maybe_unused)  	pr_debug("\nfiltering all but fda->entries[2]:");  	fdarray__fprintf_prefix(fda, "before", stderr); -	nr_fds = fdarray__filter(fda, POLLHUP, NULL); +	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);  	fdarray__fprintf_prefix(fda, " after", stderr);  	if (nr_fds != 1) {  		pr_debug("\nfdarray__filter()=%d != 1, should have left just one event", nr_fds); @@ -78,7 +79,7 @@ int test__fdarray__filter(int subtest __maybe_unused)  	pr_debug("\nfiltering all but (fda->entries[0], fda->entries[3]):");  	fdarray__fprintf_prefix(fda, "before", stderr); -	nr_fds = fdarray__filter(fda, POLLHUP, NULL); +	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);  	fdarray__fprintf_prefix(fda, " after", stderr);  	if (nr_fds != 2) {  		pr_debug("\nfdarray__filter()=%d != 2, should have left just two events", diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index a9e3db3afac4..9fd54b79a788 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -216,6 +216,8 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec  		/* check callchain entries */  		root = &he->callchain->node.rb_root; + +		TEST_ASSERT_VAL("callchains expected", !RB_EMPTY_ROOT(root));  		cnode = rb_entry(rb_first(root), struct callchain_node, rb_node);  		c = 0; @@ -666,6 +668,8 @@ static int test4(struct perf_evsel *evsel, struct machine *machine)  	perf_evsel__set_sample_bit(evsel, CALLCHAIN);  	setup_sorting(NULL); + +	callchain_param = callchain_param_default;  	callchain_register_param(&callchain_param);  	err = add_hist_entries(hists, machine); diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index e846f8c42013..62efb14f3a5a 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -56,7 +56,7 @@ static int add_hist_entries(struct perf_evlist *evlist,  	 * (perf [perf] main) will be collapsed to an existing entry  	 * so total 9 entries will be in the tree.  	 */ -	evlist__for_each(evlist, evsel) { +	evlist__for_each_entry(evlist, evsel) {  		for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {  			struct hist_entry_iter iter = {  				.evsel = evsel, @@ -136,7 +136,7 @@ int test__hists_filter(int subtest __maybe_unused)  	if (err < 0)  		goto out; -	evlist__for_each(evlist, evsel) { +	evlist__for_each_entry(evlist, evsel) {  		struct hists *hists = evsel__hists(evsel);  		hists__collapse_resort(hists, NULL); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index acf5a1301c07..eddc7407ff8a 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -72,7 +72,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)  	 * However the second evsel also has a collapsed entry for  	 * "bash [libc] malloc" so total 9 entries will be in the tree.  	 */ -	evlist__for_each(evlist, evsel) { +	evlist__for_each_entry(evlist, evsel) {  		struct hists *hists = evsel__hists(evsel);  		for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { @@ -84,7 +84,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)  			if (machine__resolve(machine, &al, &sample) < 0)  				goto out; -			he = __hists__add_entry(hists, &al, NULL, +			he = hists__add_entry(hists, &al, NULL,  						NULL, NULL, &sample, true);  			if (he == NULL) {  				addr_location__put(&al); @@ -103,7 +103,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)  			if (machine__resolve(machine, &al, &sample) < 0)  				goto out; -			he = __hists__add_entry(hists, &al, NULL, +			he = hists__add_entry(hists, &al, NULL,  						NULL, NULL, &sample, true);  			if (he == NULL) {  				addr_location__put(&al); @@ -301,7 +301,7 @@ int test__hists_link(int subtest __maybe_unused)  	if (err < 0)  		goto out; -	evlist__for_each(evlist, evsel) { +	evlist__for_each_entry(evlist, evsel) {  		hists = evsel__hists(evsel);  		hists__collapse_resort(hists, NULL); diff --git a/tools/perf/tests/is_printable_array.c b/tools/perf/tests/is_printable_array.c new file mode 100644 index 000000000000..42e13393e502 --- /dev/null +++ b/tools/perf/tests/is_printable_array.c @@ -0,0 +1,36 @@ +#include <linux/compiler.h> +#include "tests.h" +#include "debug.h" +#include "util.h" + +int test__is_printable_array(int subtest __maybe_unused) +{ +	char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 }; +	char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 }; +	struct { +		char		*buf; +		unsigned int	 len; +		int		 ret; +	} t[] = { +		{ (char *) "krava",	sizeof("krava"),	1 }, +		{ (char *) "krava",	sizeof("krava") - 1,	0 }, +		{ (char *) "",		sizeof(""),		1 }, +		{ (char *) "",		0,			0 }, +		{ NULL,			0,			0 }, +		{ buf1,			sizeof(buf1),		0 }, +		{ buf2,			sizeof(buf2),		0 }, +	}; +	unsigned int i; + +	for (i = 0; i < ARRAY_SIZE(t); i++) { +		int ret; + +		ret = is_printable_array((char *) t[i].buf, t[i].len); +		if (ret != t[i].ret) { +			pr_err("failed: test %u\n", i); +			return TEST_FAIL; +		} +	} + +	return TEST_OK; +} diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c index d2af78193153..76f41f249944 100644 --- a/tools/perf/tests/kmod-path.c +++ b/tools/perf/tests/kmod-path.c @@ -1,4 +1,5 @@  #include <stdbool.h> +#include <stdlib.h>  #include "tests.h"  #include "dso.h"  #include "debug.h" diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index cff564fb4b66..b798a4bfd238 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -5,6 +5,7 @@  #include "llvm.h"  #include "tests.h"  #include "debug.h" +#include "util.h"  #ifdef HAVE_LIBBPF_SUPPORT  static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) diff --git a/tools/perf/tests/make b/tools/perf/tests/make index cac15d93aea6..143f4d549769 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -81,6 +81,8 @@ make_no_libbionic   := NO_LIBBIONIC=1  make_no_auxtrace    := NO_AUXTRACE=1  make_no_libbpf	    := NO_LIBBPF=1  make_no_libcrypto   := NO_LIBCRYPTO=1 +make_with_babeltrace:= LIBBABELTRACE=1 +make_no_sdt	    := NO_SDT=1  make_tags           := tags  make_cscope         := cscope  make_help           := help @@ -104,7 +106,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 +make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1  # $(run) contains all available tests  run := make_pure @@ -136,6 +138,7 @@ run += make_no_libaudit  run += make_no_libbionic  run += make_no_auxtrace  run += make_no_libbpf +run += make_with_babeltrace  run += make_help  run += make_doc  run += make_perf_o diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 359e98fcd94c..634bce9caebd 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -1,3 +1,6 @@ +/* For the CLR_() macros */ +#include <pthread.h> +  #include "evlist.h"  #include "evsel.h"  #include "thread_map.h" @@ -49,7 +52,7 @@ int test__basic_mmap(int subtest __maybe_unused)  	sched_setaffinity(0, sizeof(cpu_set), &cpu_set);  	if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {  		pr_debug("sched_setaffinity() failed on CPU %d: %s ", -			 cpus->map[0], strerror_r(errno, sbuf, sizeof(sbuf))); +			 cpus->map[0], str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_free_cpus;  	} @@ -79,7 +82,7 @@ int test__basic_mmap(int subtest __maybe_unused)  		if (perf_evsel__open(evsels[i], cpus, threads) < 0) {  			pr_debug("failed to open counter: %s, "  				 "tweak /proc/sys/kernel/perf_event_paranoid?\n", -				 strerror_r(errno, sbuf, sizeof(sbuf))); +				 str_error_r(errno, sbuf, sizeof(sbuf)));  			goto out_delete_evlist;  		} @@ -89,7 +92,7 @@ int test__basic_mmap(int subtest __maybe_unused)  	if (perf_evlist__mmap(evlist, 128, true) < 0) {  		pr_debug("failed to mmap events: %d (%s)\n", errno, -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} @@ -126,7 +129,7 @@ int test__basic_mmap(int subtest __maybe_unused)  	}  	err = 0; -	evlist__for_each(evlist, evsel) { +	evlist__for_each_entry(evlist, evsel) {  		if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {  			pr_debug("expected %d %s events, got %d\n",  				 expected_nr_events[evsel->idx], diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index ad1cb63139a7..c8d9592eb142 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -1,3 +1,6 @@ +/* For the CPU_* macros */ +#include <pthread.h> +  #include <api/fs/fs.h>  #include <linux/err.h>  #include "evsel.h" @@ -41,7 +44,7 @@ int test__openat_syscall_event_on_all_cpus(int subtest __maybe_unused)  	if (perf_evsel__open(evsel, cpus, threads) < 0) {  		pr_debug("failed to open counter: %s, "  			 "tweak /proc/sys/kernel/perf_event_paranoid?\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_evsel_delete;  	} @@ -62,7 +65,7 @@ int test__openat_syscall_event_on_all_cpus(int subtest __maybe_unused)  		if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {  			pr_debug("sched_setaffinity() failed on CPU %d: %s ",  				 cpus->map[cpu], -				 strerror_r(errno, sbuf, sizeof(sbuf))); +				 str_error_r(errno, sbuf, sizeof(sbuf)));  			goto out_close_fd;  		}  		for (i = 0; i < ncalls; ++i) { diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 4344fe482c1d..f52239fed361 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -6,6 +6,13 @@  #include "tests.h"  #include "debug.h" +#ifndef O_DIRECTORY +#define O_DIRECTORY    00200000 +#endif +#ifndef AT_FDCWD +#define AT_FDCWD       -100 +#endif +  int test__syscall_openat_tp_fields(int subtest __maybe_unused)  {  	struct record_opts opts = { @@ -51,14 +58,14 @@ int test__syscall_openat_tp_fields(int subtest __maybe_unused)  	err = perf_evlist__open(evlist);  	if (err < 0) {  		pr_debug("perf_evlist__open: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	}  	err = perf_evlist__mmap(evlist, UINT_MAX, false);  	if (err < 0) {  		pr_debug("perf_evlist__mmap: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 1184f9ba6499..d7414128d7fe 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -29,7 +29,7 @@ int test__openat_syscall_event(int subtest __maybe_unused)  	if (perf_evsel__open_per_thread(evsel, threads) < 0) {  		pr_debug("failed to open counter: %s, "  			 "tweak /proc/sys/kernel/perf_event_paranoid?\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_evsel_delete;  	} diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 7865f68dc0d8..20c2e641c422 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -32,7 +32,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)  	TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);  	TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups); -	evlist__for_each(evlist, evsel) { +	evlist__for_each_entry(evlist, evsel) {  		TEST_ASSERT_VAL("wrong type",  			PERF_TYPE_TRACEPOINT == evsel->attr.type);  		TEST_ASSERT_VAL("wrong sample_type", @@ -207,7 +207,7 @@ test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist)  	TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); -	evlist__for_each(evlist, evsel) { +	evlist__for_each_entry(evlist, evsel) {  		TEST_ASSERT_VAL("wrong exclude_user",  				!evsel->attr.exclude_user);  		TEST_ASSERT_VAL("wrong exclude_kernel", @@ -1783,8 +1783,8 @@ static int test_pmu_events(void)  		struct evlist_test e;  		char name[MAX_NAME]; -		if (!strcmp(ent->d_name, ".") || -		    !strcmp(ent->d_name, "..")) +		/* Names containing . are special and cannot be used directly */ +		if (strchr(ent->d_name, '.'))  			continue;  		snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name); diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index 294c76b01b41..81c6eeaca0f5 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -44,8 +44,7 @@ static int process_events(union perf_event **events, size_t count)  	for (i = 0; i < count && !err; i++)  		err = process_event(&evlist, events[i]); -	if (evlist) -		perf_evlist__delete(evlist); +	perf_evlist__delete(evlist);  	return err;  } diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index b836ee6a8d9b..8f2e1de6d0ea 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -1,3 +1,6 @@ +/* For the CLR_() macros */ +#include <pthread.h> +  #include <sched.h>  #include "evlist.h"  #include "evsel.h" @@ -104,7 +107,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)  	err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);  	if (err < 0) {  		pr_debug("sched__get_first_possible_cpu: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} @@ -115,7 +118,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)  	 */  	if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) {  		pr_debug("sched_setaffinity: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} @@ -126,7 +129,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)  	err = perf_evlist__open(evlist);  	if (err < 0) {  		pr_debug("perf_evlist__open: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} @@ -138,7 +141,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)  	err = perf_evlist__mmap(evlist, opts.mmap_pages, false);  	if (err < 0) {  		pr_debug("perf_evlist__mmap: %s\n", -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c new file mode 100644 index 000000000000..f59d210e1baf --- /dev/null +++ b/tools/perf/tests/sdt.c @@ -0,0 +1,115 @@ +#include <stdio.h> +#include <sys/epoll.h> +#include <util/util.h> +#include <util/evlist.h> +#include <linux/filter.h> +#include "tests.h" +#include "debug.h" +#include "probe-file.h" +#include "build-id.h" + +/* To test SDT event, we need libelf support to scan elf binary */ +#if defined(HAVE_SDT_EVENT) && defined(HAVE_LIBELF_SUPPORT) + +#include <sys/sdt.h> + +static int target_function(void) +{ +	DTRACE_PROBE(perf, test_target); +	return TEST_OK; +} + +/* Copied from builtin-buildid-cache.c */ +static int build_id_cache__add_file(const char *filename) +{ +	char sbuild_id[SBUILD_ID_SIZE]; +	u8 build_id[BUILD_ID_SIZE]; +	int err; + +	err = filename__read_build_id(filename, &build_id, sizeof(build_id)); +	if (err < 0) { +		pr_debug("Failed to read build id of %s\n", filename); +		return err; +	} + +	build_id__sprintf(build_id, sizeof(build_id), sbuild_id); +	err = build_id_cache__add_s(sbuild_id, filename, false, false); +	if (err < 0) +		pr_debug("Failed to add build id cache of %s\n", filename); +	return err; +} + +static char *get_self_path(void) +{ +	char *buf = calloc(PATH_MAX, sizeof(char)); + +	if (buf && readlink("/proc/self/exe", buf, PATH_MAX) < 0) { +		pr_debug("Failed to get correct path of perf\n"); +		free(buf); +		return NULL; +	} +	return buf; +} + +static int search_cached_probe(const char *target, +			       const char *group, const char *event) +{ +	struct probe_cache *cache = probe_cache__new(target); +	int ret = 0; + +	if (!cache) { +		pr_debug("Failed to open probe cache of %s\n", target); +		return -EINVAL; +	} + +	if (!probe_cache__find_by_name(cache, group, event)) { +		pr_debug("Failed to find %s:%s in the cache\n", group, event); +		ret = -ENOENT; +	} +	probe_cache__delete(cache); + +	return ret; +} + +int test__sdt_event(int subtests __maybe_unused) +{ +	int ret = TEST_FAIL; +	char __tempdir[] = "./test-buildid-XXXXXX"; +	char *tempdir = NULL, *myself = get_self_path(); + +	if (myself == NULL || mkdtemp(__tempdir) == NULL) { +		pr_debug("Failed to make a tempdir for build-id cache\n"); +		goto error; +	} +	/* Note that buildid_dir must be an absolute path */ +	tempdir = realpath(__tempdir, NULL); + +	/* At first, scan itself */ +	set_buildid_dir(tempdir); +	if (build_id_cache__add_file(myself) < 0) +		goto error_rmdir; + +	/* Open a cache and make sure the SDT is stored */ +	if (search_cached_probe(myself, "sdt_perf", "test_target") < 0) +		goto error_rmdir; + +	/* TBD: probing on the SDT event and collect logs */ + +	/* Call the target and get an event */ +	ret = target_function(); + +error_rmdir: +	/* Cleanup temporary buildid dir */ +	rm_rf(tempdir); +error: +	free(tempdir); +	free(myself); +	return ret; +} +#else +int test__sdt_event(int subtests __maybe_unused) +{ +	pr_debug("Skip SDT event test because SDT support is not compiled\n"); +	return TEST_SKIP; +} +#endif diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 36e8ce1550e3..4c9fd046d57b 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -70,7 +70,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)  		err = -errno;  		pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n", -			 strerror_r(errno, sbuf, sizeof(sbuf)), +			 str_error_r(errno, sbuf, sizeof(sbuf)),  			 knob, (u64)attr.sample_freq);  		goto out_delete_evlist;  	} @@ -78,7 +78,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)  	err = perf_evlist__mmap(evlist, 128, true);  	if (err < 0) {  		pr_debug("failed to mmap event: %d (%s)\n", errno, -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 39a689bf7574..7ddbe267d0ac 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -432,7 +432,7 @@ int test__switch_tracking(int subtest __maybe_unused)  	}  	/* Check non-tracking events are not tracking */ -	evlist__for_each(evlist, evsel) { +	evlist__for_each_entry(evlist, evsel) {  		if (evsel != tracking_evsel) {  			if (evsel->attr.mmap || evsel->attr.comm) {  				pr_debug("Non-tracking event is tracking\n"); diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 2dfff7ac8ef3..01a5ba2788c6 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -91,13 +91,13 @@ int test__task_exit(int subtest __maybe_unused)  	err = perf_evlist__open(evlist);  	if (err < 0) {  		pr_debug("Couldn't open the evlist: %s\n", -			 strerror_r(-err, sbuf, sizeof(sbuf))); +			 str_error_r(-err, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	}  	if (perf_evlist__mmap(evlist, 128, true) < 0) {  		pr_debug("failed to mmap events: %d (%s)\n", errno, -			 strerror_r(errno, sbuf, sizeof(sbuf))); +			 str_error_r(errno, sbuf, sizeof(sbuf)));  		goto out_delete_evlist;  	} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index c57e72c826d2..9bfc0e06c61a 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -87,6 +87,9 @@ int test__synthesize_stat_round(int subtest);  int test__event_update(int subtest);  int test__event_times(int subtest);  int test__backward_ring_buffer(int subtest); +int test__cpu_map_print(int subtest); +int test__sdt_event(int subtest); +int test__is_printable_array(int subtest);  #if defined(__arm__) || defined(__aarch64__)  #ifdef HAVE_DWARF_UNWIND_SUPPORT diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index fccde848fe9c..cee2a2cdc933 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -1,13 +1,20 @@  #include <sys/types.h>  #include <unistd.h> +#include <sys/prctl.h>  #include "tests.h"  #include "thread_map.h"  #include "debug.h" +#define NAME	(const char *) "perf" +#define NAMEUL	(unsigned long) NAME +  int test__thread_map(int subtest __maybe_unused)  {  	struct thread_map *map; +	TEST_ASSERT_VAL("failed to set process name", +			!prctl(PR_SET_NAME, NAMEUL, 0, 0, 0)); +  	/* test map on current pid */  	map = thread_map__new_by_pid(getpid());  	TEST_ASSERT_VAL("failed to alloc map", map); @@ -19,7 +26,7 @@ int test__thread_map(int subtest __maybe_unused)  			thread_map__pid(map, 0) == getpid());  	TEST_ASSERT_VAL("wrong comm",  			thread_map__comm(map, 0) && -			!strcmp(thread_map__comm(map, 0), "perf")); +			!strcmp(thread_map__comm(map, 0), NAME));  	TEST_ASSERT_VAL("wrong refcnt",  			atomic_read(&map->refcnt) == 1);  	thread_map__put(map); @@ -51,7 +58,7 @@ static int process_event(struct perf_tool *tool __maybe_unused,  	TEST_ASSERT_VAL("wrong nr",   map->nr == 1);  	TEST_ASSERT_VAL("wrong pid",  map->entries[0].pid == (u64) getpid()); -	TEST_ASSERT_VAL("wrong comm", !strcmp(map->entries[0].comm, "perf")); +	TEST_ASSERT_VAL("wrong comm", !strcmp(map->entries[0].comm, NAME));  	threads = thread_map__new_event(&event->thread_map);  	TEST_ASSERT_VAL("failed to alloc map", threads); @@ -61,7 +68,7 @@ static int process_event(struct perf_tool *tool __maybe_unused,  			thread_map__pid(threads, 0) == getpid());  	TEST_ASSERT_VAL("wrong comm",  			thread_map__comm(threads, 0) && -			!strcmp(thread_map__comm(threads, 0), "perf")); +			!strcmp(thread_map__comm(threads, 0), NAME));  	TEST_ASSERT_VAL("wrong refcnt",  			atomic_read(&threads->refcnt) == 1);  	thread_map__put(threads); @@ -72,6 +79,9 @@ int test__thread_map_synthesize(int subtest __maybe_unused)  {  	struct thread_map *threads; +	TEST_ASSERT_VAL("failed to set process name", +			!prctl(PR_SET_NAME, NAMEUL, 0, 0, 0)); +  	/* test map on current pid */  	threads = thread_map__new_by_pid(getpid());  	TEST_ASSERT_VAL("failed to alloc map", threads);  |