Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  bp_account.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * 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 <fcntl.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"

/*
 * PowerPC and S390 do not support creation of instruction breakpoints using the
 * perf_event interface.
 *
 * Just disable the test for these architectures until these issues are
 * resolved.
 */

#if defined(__powerpc__) || defined(__s390x__)
#define BP_ACCOUNT_IS_SUPPORTED 0
#else
#define BP_ACCOUNT_IS_SUPPORTED 1
#endif

static volatile long the_var;

static noinline int test_function(void)
{
 return 0;
}

static int __event(bool is_x, void *addr, struct perf_event_attr *attr)
{
 int fd;

 memset(attr, 0, sizeof(struct perf_event_attr));
 attr->type = PERF_TYPE_BREAKPOINT;
 attr->size = sizeof(struct perf_event_attr);

 attr->config = 0;
 attr->bp_type = is_x ? HW_BREAKPOINT_X : HW_BREAKPOINT_W;
 attr->bp_addr = (unsigned long) addr;
 attr->bp_len = is_x ? default_breakpoint_len() : sizeof(long);

 attr->sample_period = 1;
 attr->sample_type = PERF_SAMPLE_IP;

 attr->exclude_kernel = 1;
 attr->exclude_hv = 1;

 fd = sys_perf_event_open(attr, -1, 0, -1,
     perf_event_open_cloexec_flag());
 if (fd < 0) {
  pr_debug("failed opening event %llx\n", attr->config);
  return TEST_FAIL;
 }

 return fd;
}

static int wp_event(void *addr, struct perf_event_attr *attr)
{
 return __event(false, addr, attr);
}

static int bp_event(void *addr, struct perf_event_attr *attr)
{
 return __event(true, addr, attr);
}

static int bp_accounting(int wp_cnt, int share)
{
 struct perf_event_attr attr, attr_mod, attr_new;
 int i, fd[wp_cnt], fd_wp, ret;

 for (i = 0; i < wp_cnt; i++) {
  fd[i] = wp_event((void *)&the_var, &attr);
  TEST_ASSERT_VAL("failed to create wp\n", fd[i] != -1);
  pr_debug("wp %d created\n", i);
 }

 attr_mod = attr;
 attr_mod.bp_type = HW_BREAKPOINT_X;
 attr_mod.bp_addr = (unsigned long) test_function;
 attr_mod.bp_len = default_breakpoint_len();

 ret = ioctl(fd[0], PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &attr_mod);
 TEST_ASSERT_VAL("failed to modify wp\n", ret == 0);

 pr_debug("wp 0 modified to bp\n");

 if (!share) {
  fd_wp = wp_event((void *)&the_var, &attr_new);
  TEST_ASSERT_VAL("failed to create max wp\n", fd_wp != -1);
  pr_debug("wp max created\n");
  close(fd_wp);
 }

 for (i = 0; i < wp_cnt; i++)
  close(fd[i]);

 return 0;
}

static int detect_cnt(bool is_x)
{
 struct perf_event_attr attr;
 void *addr = is_x ? (void *)test_function : (void *)&the_var;
 int fd[100], cnt = 0, i;

 while (1) {
  if (cnt == 100) {
   pr_debug("way too many debug registers, fix the test\n");
   return 0;
  }
  fd[cnt] = __event(is_x, addr, &attr);

  if (fd[cnt] < 0)
   break;
  cnt++;
 }

 for (i = 0; i < cnt; i++)
  close(fd[i]);

 return cnt;
}

static int detect_ioctl(void)
{
 struct perf_event_attr attr;
 int fd, ret = 1;

 fd = wp_event((void *) &the_var, &attr);
 if (fd > 0) {
  ret = ioctl(fd, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &attr);
  close(fd);
 }

 return ret ? 0 : 1;
}

static int detect_share(int wp_cnt, int bp_cnt)
{
 struct perf_event_attr attr;
 int i, *fd = NULL, ret = -1;

 if (wp_cnt + bp_cnt == 0)
  return 0;

 fd = malloc(sizeof(int) * (wp_cnt + bp_cnt));
 if (!fd)
  return -1;

 for (i = 0; i < wp_cnt; i++) {
  fd[i] = wp_event((void *)&the_var, &attr);
  if (fd[i] == -1) {
   pr_err("failed to create wp\n");
   goto out;
  }
 }

 for (; i < (bp_cnt + wp_cnt); i++) {
  fd[i] = bp_event((void *)test_function, &attr);
  if (fd[i] == -1)
   break;
 }

 ret = i != (bp_cnt + wp_cnt);

out:
 while (i--)
  close(fd[i]);

 free(fd);
 return ret;
}

/*
 * This test does following:
 *   - detects the number of watch/break-points,
 *     skip test if any is missing
 *   - detects PERF_EVENT_IOC_MODIFY_ATTRIBUTES ioctl,
 *     skip test if it's missing
 *   - detects if watchpoints and breakpoints share
 *     same slots
 *   - create all possible watchpoints on cpu 0
 *   - change one of it to breakpoint
 *   - in case wp and bp do not share slots,
 *     we create another watchpoint to ensure
 *     the slot accounting is correct
 */

static int test__bp_accounting(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
 int has_ioctl = detect_ioctl();
 int wp_cnt = detect_cnt(false);
 int bp_cnt = detect_cnt(true);
 int share  = detect_share(wp_cnt, bp_cnt);

 if (!BP_ACCOUNT_IS_SUPPORTED) {
  pr_debug("Test not supported on this architecture");
  return TEST_SKIP;
 }

 pr_debug("watchpoints count %d, breakpoints count %d, has_ioctl %d, share %d\n",
   wp_cnt, bp_cnt, has_ioctl, share);

 if (!wp_cnt || !bp_cnt || !has_ioctl)
  return TEST_SKIP;

 return bp_accounting(wp_cnt, share);
}

DEFINE_SUITE("Breakpoint accounting", bp_accounting);

Messung V0.5
C=100 H=98 G=98

¤ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge