Arnaldo Carvalho de Melo | a43783a | 2017-04-18 10:46:11 -0300 | [diff] [blame] | 1 | #include <errno.h> |
Masami Hiramatsu | 8e5dc84 | 2016-07-12 19:06:05 +0900 | [diff] [blame] | 2 | #include <stdio.h> |
| 3 | #include <sys/epoll.h> |
Masami Hiramatsu | 8e5dc84 | 2016-07-12 19:06:05 +0900 | [diff] [blame] | 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 | |
Tommi Rantala | 0e6ba11 | 2017-03-22 15:06:21 +0200 | [diff] [blame] | 46 | if (buf && readlink("/proc/self/exe", buf, PATH_MAX - 1) < 0) { |
Masami Hiramatsu | 8e5dc84 | 2016-07-12 19:06:05 +0900 | [diff] [blame] | 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 |