static int test_debug_fs_uprobe()

in bpf/task_fd_query_user.c [228:309]


static int test_debug_fs_uprobe(char *binary_path, long offset, bool is_return)
{
	char buf[256], event_alias[sizeof("test_1234567890")];
	const char *event_type = "uprobe";
	struct perf_event_attr attr = {};
	__u64 probe_offset, probe_addr;
	__u32 len, prog_id, fd_type;
	int err = -1, res, kfd, efd;
	struct bpf_link *link;
	ssize_t bytes;

	snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/%s_events",
		 event_type);
	kfd = open(buf, O_WRONLY | O_TRUNC, 0);
	CHECK_PERROR_RET(kfd < 0);

	res = snprintf(event_alias, sizeof(event_alias), "test_%d", getpid());
	CHECK_PERROR_RET(res < 0 || res >= sizeof(event_alias));

	res = snprintf(buf, sizeof(buf), "%c:%ss/%s %s:0x%lx",
		       is_return ? 'r' : 'p', event_type, event_alias,
		       binary_path, offset);
	CHECK_PERROR_RET(res < 0 || res >= sizeof(buf));
	CHECK_PERROR_RET(write(kfd, buf, strlen(buf)) < 0);

	close(kfd);
	kfd = -1;

	snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/events/%ss/%s/id",
		 event_type, event_alias);
	efd = open(buf, O_RDONLY, 0);
	CHECK_PERROR_RET(efd < 0);

	bytes = read(efd, buf, sizeof(buf));
	CHECK_PERROR_RET(bytes <= 0 || bytes >= sizeof(buf));
	close(efd);
	buf[bytes] = '\0';

	attr.config = strtol(buf, NULL, 0);
	attr.type = PERF_TYPE_TRACEPOINT;
	attr.sample_period = 1;
	attr.wakeup_events = 1;

	kfd = sys_perf_event_open(&attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC);
	link = bpf_program__attach_perf_event(progs[0], kfd);
	if (libbpf_get_error(link)) {
		printf("ERROR: bpf_program__attach_perf_event failed\n");
		link = NULL;
		close(kfd);
		goto cleanup;
	}

	len = sizeof(buf);
	err = bpf_task_fd_query(getpid(), kfd, 0, buf, &len,
				&prog_id, &fd_type, &probe_offset,
				&probe_addr);
	if (err < 0) {
		printf("FAIL: %s, binary_path %s\n", __func__, binary_path);
		perror("    :");
		return -1;
	}
	if ((is_return && fd_type != BPF_FD_TYPE_URETPROBE) ||
	    (!is_return && fd_type != BPF_FD_TYPE_UPROBE)) {
		printf("FAIL: %s, incorrect fd_type %u\n", __func__,
		       fd_type);
		return -1;
	}
	if (strcmp(binary_path, buf) != 0) {
		printf("FAIL: %s, incorrect buf %s\n", __func__, buf);
		return -1;
	}
	if (probe_offset != offset) {
		printf("FAIL: %s, incorrect probe_offset 0x%llx\n", __func__,
		       probe_offset);
		return -1;
	}
	err = 0;

cleanup:
	bpf_link__destroy(link);
	return err;
}