tools/testing/selftests/proc/proc-empty-vm.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/proc/proc-empty-vm.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/proc/proc-empty-vm.c
Extension
.c
Size
13343 bytes
Lines
542
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

setrlimit(RLIMIT_CORE, &(struct rlimit){});

		/* Hide "segfault at ffffffffff600000" messages. */
		struct sigaction act = {};
		act.sa_flags = SA_SIGINFO;
		act.sa_sigaction = sigaction_SIGSEGV_vsyscall;
		sigaction(SIGSEGV, &act, NULL);

		g_vsyscall = 0;
		/* gettimeofday(NULL, NULL); */
		uint64_t rax = 0xffffffffff600000;
		asm volatile (
			"call *%[rax]"
			: [rax] "+a" (rax)
			: "D" (NULL), "S" (NULL)
			: "rcx", "r11"
		);

		g_vsyscall = 1;
		*(volatile int *)0xffffffffff600000UL;

		g_vsyscall = 2;
		exit(g_vsyscall);
	}
	waitpid(pid, &wstatus, 0);
	if (WIFEXITED(wstatus)) {
		g_vsyscall = WEXITSTATUS(wstatus);
	} else {
		fprintf(stderr, "error: vsyscall wstatus %08x\n", wstatus);
		exit(1);
	}
}
#endif

static int test_proc_pid_maps(pid_t pid)
{
	char buf[4096];
	snprintf(buf, sizeof(buf), "/proc/%u/maps", pid);
	int fd = open(buf, O_RDONLY);
	if (fd == -1) {
		perror("open /proc/${pid}/maps");
		return EXIT_FAILURE;
	} else {
		ssize_t rv = read(fd, buf, sizeof(buf));
		close(fd);
		if (g_vsyscall == 0) {
			assert(rv == 0);
		} else {
			size_t len = strlen(g_proc_pid_maps_vsyscall);
			assert(rv == len);
			assert(memcmp(buf, g_proc_pid_maps_vsyscall, len) == 0);
		}
		return EXIT_SUCCESS;
	}
}

static int test_proc_pid_numa_maps(pid_t pid)
{
	char buf[4096];
	snprintf(buf, sizeof(buf), "/proc/%u/numa_maps", pid);
	int fd = open(buf, O_RDONLY);
	if (fd == -1) {
		if (errno == ENOENT) {
			/*
			 * /proc/${pid}/numa_maps is under CONFIG_NUMA,
			 * it doesn't necessarily exist.
			 */
			return EXIT_SUCCESS;
		}
		perror("open /proc/${pid}/numa_maps");
		return EXIT_FAILURE;
	} else {
		ssize_t rv = read(fd, buf, sizeof(buf));
		close(fd);
		assert(rv == 0);
		return EXIT_SUCCESS;
	}
}

static int test_proc_pid_smaps(pid_t pid)
{
	char buf[4096];
	snprintf(buf, sizeof(buf), "/proc/%u/smaps", pid);
	int fd = open(buf, O_RDONLY);
	if (fd == -1) {
		if (errno == ENOENT) {
			/*
			 * /proc/${pid}/smaps is under CONFIG_PROC_PAGE_MONITOR,
			 * it doesn't necessarily exist.
			 */

Annotation

Implementation Notes