xref: /linux/tools/perf/tests/sdt.c (revision b6ebbac51bedf9e98e837688bc838f400196da5e)
1 #include <stdio.h>
2 #include <sys/epoll.h>
3 #include <util/util.h>
4 #include <util/evlist.h>
5 #include <linux/filter.h>
6 #include "tests.h"
7 #include "debug.h"
8 #include "probe-file.h"
9 #include "build-id.h"
10 
11 /* To test SDT event, we need libelf support to scan elf binary */
12 #if defined(HAVE_SDT_EVENT) && defined(HAVE_LIBELF_SUPPORT)
13 
14 #include <sys/sdt.h>
15 
16 static int target_function(void)
17 {
18 	DTRACE_PROBE(perf, test_target);
19 	return TEST_OK;
20 }
21 
22 /* Copied from builtin-buildid-cache.c */
23 static int build_id_cache__add_file(const char *filename)
24 {
25 	char sbuild_id[SBUILD_ID_SIZE];
26 	u8 build_id[BUILD_ID_SIZE];
27 	int err;
28 
29 	err = filename__read_build_id(filename, &build_id, sizeof(build_id));
30 	if (err < 0) {
31 		pr_debug("Failed to read build id of %s\n", filename);
32 		return err;
33 	}
34 
35 	build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
36 	err = build_id_cache__add_s(sbuild_id, filename, false, false);
37 	if (err < 0)
38 		pr_debug("Failed to add build id cache of %s\n", filename);
39 	return err;
40 }
41 
42 static char *get_self_path(void)
43 {
44 	char *buf = calloc(PATH_MAX, sizeof(char));
45 
46 	if (buf && readlink("/proc/self/exe", buf, PATH_MAX) < 0) {
47 		pr_debug("Failed to get correct path of perf\n");
48 		free(buf);
49 		return NULL;
50 	}
51 	return buf;
52 }
53 
54 static int search_cached_probe(const char *target,
55 			       const char *group, const char *event)
56 {
57 	struct probe_cache *cache = probe_cache__new(target);
58 	int ret = 0;
59 
60 	if (!cache) {
61 		pr_debug("Failed to open probe cache of %s\n", target);
62 		return -EINVAL;
63 	}
64 
65 	if (!probe_cache__find_by_name(cache, group, event)) {
66 		pr_debug("Failed to find %s:%s in the cache\n", group, event);
67 		ret = -ENOENT;
68 	}
69 	probe_cache__delete(cache);
70 
71 	return ret;
72 }
73 
74 int test__sdt_event(int subtests __maybe_unused)
75 {
76 	int ret = TEST_FAIL;
77 	char __tempdir[] = "./test-buildid-XXXXXX";
78 	char *tempdir = NULL, *myself = get_self_path();
79 
80 	if (myself == NULL || mkdtemp(__tempdir) == NULL) {
81 		pr_debug("Failed to make a tempdir for build-id cache\n");
82 		goto error;
83 	}
84 	/* Note that buildid_dir must be an absolute path */
85 	tempdir = realpath(__tempdir, NULL);
86 
87 	/* At first, scan itself */
88 	set_buildid_dir(tempdir);
89 	if (build_id_cache__add_file(myself) < 0)
90 		goto error_rmdir;
91 
92 	/* Open a cache and make sure the SDT is stored */
93 	if (search_cached_probe(myself, "sdt_perf", "test_target") < 0)
94 		goto error_rmdir;
95 
96 	/* TBD: probing on the SDT event and collect logs */
97 
98 	/* Call the target and get an event */
99 	ret = target_function();
100 
101 error_rmdir:
102 	/* Cleanup temporary buildid dir */
103 	rm_rf(tempdir);
104 error:
105 	free(tempdir);
106 	free(myself);
107 	return ret;
108 }
109 #else
110 int test__sdt_event(int subtests __maybe_unused)
111 {
112 	pr_debug("Skip SDT event test because SDT support is not compiled\n");
113 	return TEST_SKIP;
114 }
115 #endif
116