tools/perf/tests/builtin-test.c

Source file repositories/reference/linux-study-clean/tools/perf/tests/builtin-test.c

File Facts

System
Linux kernel
Corpus path
tools/perf/tests/builtin-test.c
Extension
.c
Size
21206 bytes
Lines
859
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct child_test {
	struct child_process process;
	struct test_suite *test;
	int suite_num;
	int test_case_num;
};

static jmp_buf run_test_jmp_buf;

static void child_test_sig_handler(int sig)
{
#ifdef HAVE_BACKTRACE_SUPPORT
	void *stackdump[32];
	size_t stackdump_size;
#endif

	fprintf(stderr, "\n---- unexpected signal (%d) ----\n", sig);
#ifdef HAVE_BACKTRACE_SUPPORT
	stackdump_size = backtrace(stackdump, ARRAY_SIZE(stackdump));
	__dump_stack(stderr, stackdump, stackdump_size);
#endif
	siglongjmp(run_test_jmp_buf, sig);
}

static int run_test_child(struct child_process *process)
{
	const int signals[] = {
		SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGINT, SIGPIPE, SIGQUIT, SIGSEGV, SIGTERM,
	};
	struct child_test *child = container_of(process, struct child_test, process);
	int err;

	close_parent_fds();

	err = sigsetjmp(run_test_jmp_buf, 1);
	if (err) {
		/* Received signal. */
		err = err > 0 ? -err : -1;
		goto err_out;
	}

	for (size_t i = 0; i < ARRAY_SIZE(signals); i++)
		signal(signals[i], child_test_sig_handler);

	pr_debug("--- start ---\n");
	pr_debug("test child forked, pid %d\n", getpid());
	err = test_function(child->test, child->test_case_num)(child->test, child->test_case_num);
	pr_debug("---- end(%d) ----\n", err);

	check_leaks();
err_out:
	fflush(NULL);
	for (size_t i = 0; i < ARRAY_SIZE(signals); i++)
		signal(signals[i], SIG_DFL);
	return -err;
}

#define TEST_RUNNING -3

static int print_test_result(struct test_suite *t, int curr_suite, int curr_test_case,
			     int result, int width, int running)
{
	if (test_suite__num_test_cases(t) > 1) {
		int subw = width > 2 ? width - 2 : width;

		pr_info("%3d.%1d: %-*s:", curr_suite + 1, curr_test_case + 1, subw,
			test_description(t, curr_test_case));
	} else
		pr_info("%3d: %-*s:", curr_suite + 1, width, test_description(t, curr_test_case));

	switch (result) {
	case TEST_RUNNING:
		color_fprintf(stderr, PERF_COLOR_YELLOW, " Running (%d active)\n", running);
		break;
	case TEST_OK:
		pr_info(" Ok\n");
		break;
	case TEST_SKIP: {
		const char *reason = skip_reason(t, curr_test_case);

		if (reason)
			color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (%s)\n", reason);
		else
			color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
	}
		break;
	case TEST_FAIL:
	default:
		color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
		break;

Annotation

Implementation Notes