tools/perf/arch/x86/tests/bp-modify.c

Source file repositories/reference/linux-study-clean/tools/perf/arch/x86/tests/bp-modify.c

File Facts

System
Linux kernel
Corpus path
tools/perf/arch/x86/tests/bp-modify.c
Extension
.c
Size
4630 bytes
Lines
209
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

if (err) {
			pr_debug("failed to PTRACE_TRACEME\n");
			exit(1);
		}

		raise(SIGCONT);
		bp_1();
		exit(0);
	}

	return child;
}

/*
 * This tests creates HW breakpoint, tries to
 * change it and checks it was properly changed.
 */
static int bp_modify1(void)
{
	pid_t child;
	int status;
	unsigned long rip = 0, dr7 = 1;

	child = spawn_child();

	waitpid(child, &status, 0);
	if (WIFEXITED(status)) {
		pr_debug("tracee exited prematurely 1\n");
		return TEST_FAIL;
	}

	/*
	 * The parent does following steps:
	 *  - creates a new breakpoint (id 0) for bp_2 function
	 *  - changes that breakpoint to bp_1 function
	 *  - waits for the breakpoint to hit and checks
	 *    it has proper rip of bp_1 function
	 *  - detaches the child
	 */
	if (ptrace(PTRACE_POKEUSER, child,
		   offsetof(struct user, u_debugreg[0]), bp_2)) {
		pr_debug("failed to set breakpoint, 1st time: %m\n");
		goto out;
	}

	if (ptrace(PTRACE_POKEUSER, child,
		   offsetof(struct user, u_debugreg[0]), bp_1)) {
		pr_debug("failed to set breakpoint, 2nd time: %m\n");
		goto out;
	}

	if (ptrace(PTRACE_POKEUSER, child,
		   offsetof(struct user, u_debugreg[7]), dr7)) {
		pr_debug("failed to set dr7: %m\n");
		goto out;
	}

	if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
		pr_debug("failed to PTRACE_CONT: %m\n");
		goto out;
	}

	waitpid(child, &status, 0);
	if (WIFEXITED(status)) {
		pr_debug("tracee exited prematurely 2\n");
		return TEST_FAIL;
	}

	rip = ptrace(PTRACE_PEEKUSER, child,
		     offsetof(struct user_regs_struct, rip), NULL);
	if (rip == (unsigned long) -1) {
		pr_debug("failed to PTRACE_PEEKUSER: %m\n");
		goto out;
	}

	pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);
out:
	if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
		pr_debug("failed to PTRACE_DETACH: %m\n");
		return TEST_FAIL;

	}
	return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
}

/*
 * This tests creates HW breakpoint, tries to
 * change it to bogus value and checks the original
 * breakpoint is hit.
 */

Annotation

Implementation Notes