tools/perf/tests/bp_signal.c

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

File Facts

System
Linux kernel
Corpus path
tools/perf/tests/bp_signal.c
Extension
.c
Size
7959 bytes
Lines
295
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

// SPDX-License-Identifier: GPL-2.0
/*
 * Inspired by breakpoint overflow test done by
 * Vince Weaver <vincent.weaver@maine.edu> for perf_event_tests
 * (git://github.com/deater/perf_event_tests)
 */

/*
 * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
 * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
 */
#define __SANE_USERSPACE_TYPES__

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/mman.h>
#include <linux/compiler.h>
#include <linux/hw_breakpoint.h>

#include "tests.h"
#include "debug.h"
#include "event.h"
#include "parse-events.h"
#include "perf-sys.h"
#include "cloexec.h"

static int fd1;
static int fd2;
static int fd3;
static int overflows;
static int overflows_2;

static volatile long the_var;


/*
 * Use ASM to ensure watchpoint and breakpoint can be triggered
 * at one instruction.
 */
#if defined (__x86_64__)
extern void __test_function(volatile long *ptr);
asm (
	".pushsection .text;"
	".globl __test_function\n"
	".type __test_function, @function;"
	"__test_function:\n"
	"incq (%rdi)\n"
	"ret\n"
	".popsection\n");
#else
static void __test_function(volatile long *ptr)
{
	*ptr = 0x1234;
}
#endif

static noinline int test_function(void)
{
	__test_function(&the_var);
	the_var++;
	return time(NULL);
}

static void sig_handler_2(int signum __maybe_unused,
			  siginfo_t *oh __maybe_unused,
			  void *uc __maybe_unused)
{
	overflows_2++;
	if (overflows_2 > 10) {
		ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
		ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
		ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
	}
}

static void sig_handler(int signum __maybe_unused,
			siginfo_t *oh __maybe_unused,
			void *uc __maybe_unused)
{
	overflows++;

	if (overflows > 10) {
		/*
		 * This should be executed only once during

Annotation

Implementation Notes