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


Quelle  ptrace-hwbreak.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0+

/*
 * Ptrace test for hw breakpoints
 *
 * Based on tools/testing/selftests/breakpoints/breakpoint_test.c
 *
 * This test forks and the parent then traces the child doing various
 * types of ptrace enabled breakpoints
 *
 * Copyright (C) 2018 Michael Neuling, IBM Corporation.
 */


#include <sys/ptrace.h>
#include <unistd.h>
#include <stddef.h>
#include <sys/user.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <linux/limits.h>
#include "ptrace.h"
#include "reg.h"

#define SPRN_PVR 0x11F
#define PVR_8xx  0x00500000

bool is_8xx;

/*
 * Use volatile on all global var so that compiler doesn't
 * optimise their load/stores. Otherwise selftest can fail.
 */

static volatile __u64 glvar;

#define DAWR_MAX_LEN 512
static volatile __u8 big_var[DAWR_MAX_LEN] __attribute__((aligned(512)));

#define A_LEN 6
#define B_LEN 6
struct gstruct {
 __u8 a[A_LEN]; /* double word aligned */
 __u8 b[B_LEN]; /* double word unaligned */
};
static volatile struct gstruct gstruct __attribute__((aligned(512)));

static volatile char cwd[PATH_MAX] __attribute__((aligned(8)));

static void get_dbginfo(pid_t child_pid, struct ppc_debug_info *dbginfo)
{
 if (ptrace(PPC_PTRACE_GETHWDBGINFO, child_pid, NULL, dbginfo)) {
  perror("Can't get breakpoint info");
  exit(-1);
 }
}

static bool dawr_present(struct ppc_debug_info *dbginfo)
{
 return !!(dbginfo->features & PPC_DEBUG_FEATURE_DATA_BP_DAWR);
}

static void write_var(int len)
{
 volatile __u8 *pcvar;
 volatile __u16 *psvar;
 volatile __u32 *pivar;
 volatile __u64 *plvar;

 switch (len) {
 case 1:
  pcvar = (volatile __u8 *)&glvar;
  *pcvar = 0xff;
  break;
 case 2:
  psvar = (volatile __u16 *)&glvar;
  *psvar = 0xffff;
  break;
 case 4:
  pivar = (volatile __u32 *)&glvar;
  *pivar = 0xffffffff;
  break;
 case 8:
  plvar = (volatile __u64 *)&glvar;
  *plvar = 0xffffffffffffffffLL;
  break;
 }
}

static void read_var(int len)
{
 __u8 cvar __attribute__((unused));
 __u16 svar __attribute__((unused));
 __u32 ivar __attribute__((unused));
 __u64 lvar __attribute__((unused));

 switch (len) {
 case 1:
  cvar = (volatile __u8)glvar;
  break;
 case 2:
  svar = (volatile __u16)glvar;
  break;
 case 4:
  ivar = (volatile __u32)glvar;
  break;
 case 8:
  lvar = (volatile __u64)glvar;
  break;
 }
}

static void test_workload(void)
{
 __u8 cvar __attribute__((unused));
 __u32 ivar __attribute__((unused));
 int len = 0;

 if (ptrace(PTRACE_TRACEME, 0, NULL, 0)) {
  perror("Child can't be traced?");
  exit(-1);
 }

 /* Wake up father so that it sets up the first test */
 kill(getpid(), SIGUSR1);

 /* PTRACE_SET_DEBUGREG, WO test */
 for (len = 1; len <= sizeof(glvar); len <<= 1)
  write_var(len);

 /* PTRACE_SET_DEBUGREG, RO test */
 for (len = 1; len <= sizeof(glvar); len <<= 1)
  read_var(len);

 /* PTRACE_SET_DEBUGREG, RW test */
 for (len = 1; len <= sizeof(glvar); len <<= 1) {
  if (rand() % 2)
   read_var(len);
  else
   write_var(len);
 }

 /* PTRACE_SET_DEBUGREG, Kernel Access Userspace test */
 syscall(__NR_getcwd, &cwd, PATH_MAX);

 /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO test */
 write_var(1);

 /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO test */
 read_var(1);

 /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW test */
 if (rand() % 2)
  write_var(1);
 else
  read_var(1);

 /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace test */
 syscall(__NR_getcwd, &cwd, PATH_MAX);

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO test */
 gstruct.a[rand() % A_LEN] = 'a';

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RO test */
 cvar = gstruct.a[rand() % A_LEN];

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RW test */
 if (rand() % 2)
  gstruct.a[rand() % A_LEN] = 'a';
 else
  cvar = gstruct.a[rand() % A_LEN];

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, WO test */
 gstruct.b[rand() % B_LEN] = 'b';

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RO test */
 cvar = gstruct.b[rand() % B_LEN];

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RW test */
 if (rand() % 2)
  gstruct.b[rand() % B_LEN] = 'b';
 else
  cvar = gstruct.b[rand() % B_LEN];

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, DAR OUTSIDE, RW test */
 if (rand() % 2)
  *((int *)(gstruct.a + 4)) = 10;
 else
  ivar = *((int *)(gstruct.a + 4));

 /* PPC_PTRACE_SETHWDEBUG. DAWR_MAX_LEN. RW test */
 if (rand() % 2)
  big_var[rand() % DAWR_MAX_LEN] = 'a';
 else
  cvar = big_var[rand() % DAWR_MAX_LEN];

 /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW ALIGNED, WO test */
 gstruct.a[rand() % A_LEN] = 'a';

 /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW UNALIGNED, RO test */
 cvar = gstruct.b[rand() % B_LEN];

 /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, WO test */
 gstruct.a[rand() % A_LEN] = 'a';

 /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, RO test */
 cvar = gstruct.a[rand() % A_LEN];
}

static void check_success(pid_t child_pid, const char *name, const char *type,
     unsigned long saddr, int len)
{
 int status;
 siginfo_t siginfo;
 unsigned long eaddr = (saddr + len - 1) | 0x7;

 saddr &= ~0x7;

 /* Wait for the child to SIGTRAP */
 wait(&status);

 ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &siginfo);

 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP ||
     (unsigned long)siginfo.si_addr < saddr ||
     (unsigned long)siginfo.si_addr > eaddr) {
  printf("%s, %s, len: %d: Fail\n", name, type, len);
  exit(-1);
 }

 printf("%s, %s, len: %d: Ok\n", name, type, len);

 if (!is_8xx) {
  /*
 * For ptrace registered watchpoint, signal is generated
 * before executing load/store. Singlestep the instruction
 * and then continue the test.
 */

  ptrace(PTRACE_SINGLESTEP, child_pid, NULL, 0);
  wait(NULL);
 }
}

static void ptrace_set_debugreg(pid_t child_pid, unsigned long wp_addr)
{
 if (ptrace(PTRACE_SET_DEBUGREG, child_pid, 0, wp_addr)) {
  perror("PTRACE_SET_DEBUGREG failed");
  exit(-1);
 }
}

static int ptrace_sethwdebug(pid_t child_pid, struct ppc_hw_breakpoint *info)
{
 int wh = ptrace(PPC_PTRACE_SETHWDEBUG, child_pid, 0, info);

 if (wh <= 0) {
  perror("PPC_PTRACE_SETHWDEBUG failed");
  exit(-1);
 }
 return wh;
}

static void ptrace_delhwdebug(pid_t child_pid, int wh)
{
 if (ptrace(PPC_PTRACE_DELHWDEBUG, child_pid, 0, wh) < 0) {
  perror("PPC_PTRACE_DELHWDEBUG failed");
  exit(-1);
 }
}

#define DABR_READ_SHIFT  0
#define DABR_WRITE_SHIFT 1
#define DABR_TRANSLATION_SHIFT 2

static int test_set_debugreg(pid_t child_pid)
{
 unsigned long wp_addr = (unsigned long)&glvar;
 char *name = "PTRACE_SET_DEBUGREG";
 int len;

 /* PTRACE_SET_DEBUGREG, WO test*/
 wp_addr &= ~0x7UL;
 wp_addr |= (1UL << DABR_WRITE_SHIFT);
 wp_addr |= (1UL << DABR_TRANSLATION_SHIFT);
 for (len = 1; len <= sizeof(glvar); len <<= 1) {
  ptrace_set_debugreg(child_pid, wp_addr);
  ptrace(PTRACE_CONT, child_pid, NULL, 0);
  check_success(child_pid, name, "WO", wp_addr, len);
 }

 /* PTRACE_SET_DEBUGREG, RO test */
 wp_addr &= ~0x7UL;
 wp_addr |= (1UL << DABR_READ_SHIFT);
 wp_addr |= (1UL << DABR_TRANSLATION_SHIFT);
 for (len = 1; len <= sizeof(glvar); len <<= 1) {
  ptrace_set_debugreg(child_pid, wp_addr);
  ptrace(PTRACE_CONT, child_pid, NULL, 0);
  check_success(child_pid, name, "RO", wp_addr, len);
 }

 /* PTRACE_SET_DEBUGREG, RW test */
 wp_addr &= ~0x7UL;
 wp_addr |= (1Ul << DABR_READ_SHIFT);
 wp_addr |= (1UL << DABR_WRITE_SHIFT);
 wp_addr |= (1UL << DABR_TRANSLATION_SHIFT);
 for (len = 1; len <= sizeof(glvar); len <<= 1) {
  ptrace_set_debugreg(child_pid, wp_addr);
  ptrace(PTRACE_CONT, child_pid, NULL, 0);
  check_success(child_pid, name, "RW", wp_addr, len);
 }

 ptrace_set_debugreg(child_pid, 0);
 return 0;
}

static int test_set_debugreg_kernel_userspace(pid_t child_pid)
{
 unsigned long wp_addr = (unsigned long)cwd;
 char *name = "PTRACE_SET_DEBUGREG";

 /* PTRACE_SET_DEBUGREG, Kernel Access Userspace test */
 wp_addr &= ~0x7UL;
 wp_addr |= (1Ul << DABR_READ_SHIFT);
 wp_addr |= (1UL << DABR_WRITE_SHIFT);
 wp_addr |= (1UL << DABR_TRANSLATION_SHIFT);
 ptrace_set_debugreg(child_pid, wp_addr);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "Kernel Access Userspace", wp_addr, 8);

 ptrace_set_debugreg(child_pid, 0);
 return 0;
}

static void get_ppc_hw_breakpoint(struct ppc_hw_breakpoint *info, int type,
      unsigned long addr, int len)
{
 info->version = 1;
 info->trigger_type = type;
 info->condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
 info->addr = (__u64)addr;
 info->addr2 = (__u64)addr + len;
 info->condition_value = 0;
 if (!len)
  info->addr_mode = PPC_BREAKPOINT_MODE_EXACT;
 else
  info->addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
}

static void test_sethwdebug_exact(pid_t child_pid)
{
 struct ppc_hw_breakpoint info;
 unsigned long wp_addr = (unsigned long)&glvar;
 char *name = "PPC_PTRACE_SETHWDEBUG, MODE_EXACT";
 int len = 1; /* hardcoded in kernel */
 int wh;

 /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO test */
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, 0);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "WO", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);

 /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO test */
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_READ, wp_addr, 0);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "RO", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);

 /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW test */
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_RW, wp_addr, 0);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "RW", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);
}

static void test_sethwdebug_exact_kernel_userspace(pid_t child_pid)
{
 struct ppc_hw_breakpoint info;
 unsigned long wp_addr = (unsigned long)&cwd;
 char *name = "PPC_PTRACE_SETHWDEBUG, MODE_EXACT";
 int len = 1; /* hardcoded in kernel */
 int wh;

 /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace test */
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, 0);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "Kernel Access Userspace", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);
}

static void test_sethwdebug_range_aligned(pid_t child_pid)
{
 struct ppc_hw_breakpoint info;
 unsigned long wp_addr;
 char *name = "PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED";
 int len;
 int wh;

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO test */
 wp_addr = (unsigned long)&gstruct.a;
 len = A_LEN;
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, len);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "WO", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RO test */
 wp_addr = (unsigned long)&gstruct.a;
 len = A_LEN;
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_READ, wp_addr, len);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "RO", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RW test */
 wp_addr = (unsigned long)&gstruct.a;
 len = A_LEN;
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_RW, wp_addr, len);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "RW", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);
}

static void test_multi_sethwdebug_range(pid_t child_pid)
{
 struct ppc_hw_breakpoint info1, info2;
 unsigned long wp_addr1, wp_addr2;
 char *name1 = "PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW ALIGNED";
 char *name2 = "PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW UNALIGNED";
 int len1, len2;
 int wh1, wh2;

 wp_addr1 = (unsigned long)&gstruct.a;
 wp_addr2 = (unsigned long)&gstruct.b;
 len1 = A_LEN;
 len2 = B_LEN;
 get_ppc_hw_breakpoint(&info1, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr1, len1);
 get_ppc_hw_breakpoint(&info2, PPC_BREAKPOINT_TRIGGER_READ, wp_addr2, len2);

 /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW ALIGNED, WO test */
 wh1 = ptrace_sethwdebug(child_pid, &info1);

 /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW UNALIGNED, RO test */
 wh2 = ptrace_sethwdebug(child_pid, &info2);

 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name1, "WO", wp_addr1, len1);

 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name2, "RO", wp_addr2, len2);

 ptrace_delhwdebug(child_pid, wh1);
 ptrace_delhwdebug(child_pid, wh2);
}

static void test_multi_sethwdebug_range_dawr_overlap(pid_t child_pid)
{
 struct ppc_hw_breakpoint info1, info2;
 unsigned long wp_addr1, wp_addr2;
 char *name = "PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap";
 int len1, len2;
 int wh1, wh2;

 wp_addr1 = (unsigned long)&gstruct.a;
 wp_addr2 = (unsigned long)&gstruct.a;
 len1 = A_LEN;
 len2 = A_LEN;
 get_ppc_hw_breakpoint(&info1, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr1, len1);
 get_ppc_hw_breakpoint(&info2, PPC_BREAKPOINT_TRIGGER_READ, wp_addr2, len2);

 /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, WO test */
 wh1 = ptrace_sethwdebug(child_pid, &info1);

 /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, RO test */
 wh2 = ptrace_sethwdebug(child_pid, &info2);

 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "WO", wp_addr1, len1);

 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "RO", wp_addr2, len2);

 ptrace_delhwdebug(child_pid, wh1);
 ptrace_delhwdebug(child_pid, wh2);
}

static void test_sethwdebug_range_unaligned(pid_t child_pid)
{
 struct ppc_hw_breakpoint info;
 unsigned long wp_addr;
 char *name = "PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED";
 int len;
 int wh;

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, WO test */
 wp_addr = (unsigned long)&gstruct.b;
 len = B_LEN;
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, len);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "WO", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RO test */
 wp_addr = (unsigned long)&gstruct.b;
 len = B_LEN;
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_READ, wp_addr, len);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "RO", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RW test */
 wp_addr = (unsigned long)&gstruct.b;
 len = B_LEN;
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_RW, wp_addr, len);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "RW", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);

}

static void test_sethwdebug_range_unaligned_dar(pid_t child_pid)
{
 struct ppc_hw_breakpoint info;
 unsigned long wp_addr;
 char *name = "PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, DAR OUTSIDE";
 int len;
 int wh;

 /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, DAR OUTSIDE, RW test */
 wp_addr = (unsigned long)&gstruct.b;
 len = B_LEN;
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, len);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "RW", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);
}

static void test_sethwdebug_dawr_max_range(pid_t child_pid)
{
 struct ppc_hw_breakpoint info;
 unsigned long wp_addr;
 char *name = "PPC_PTRACE_SETHWDEBUG, DAWR_MAX_LEN";
 int len;
 int wh;

 /* PPC_PTRACE_SETHWDEBUG, DAWR_MAX_LEN, RW test */
 wp_addr = (unsigned long)big_var;
 len = DAWR_MAX_LEN;
 get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_RW, wp_addr, len);
 wh = ptrace_sethwdebug(child_pid, &info);
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 check_success(child_pid, name, "RW", wp_addr, len);
 ptrace_delhwdebug(child_pid, wh);
}

/* Set the breakpoints and check the child successfully trigger them */
static void
run_tests(pid_t child_pid, struct ppc_debug_info *dbginfo, bool dawr)
{
 test_set_debugreg(child_pid);
 test_set_debugreg_kernel_userspace(child_pid);
 test_sethwdebug_exact(child_pid);
 test_sethwdebug_exact_kernel_userspace(child_pid);
 if (dbginfo->features & PPC_DEBUG_FEATURE_DATA_BP_RANGE) {
  test_sethwdebug_range_aligned(child_pid);
  if (dawr || is_8xx) {
   test_sethwdebug_range_unaligned(child_pid);
   test_sethwdebug_range_unaligned_dar(child_pid);
   test_sethwdebug_dawr_max_range(child_pid);
   if (dbginfo->num_data_bps > 1) {
    test_multi_sethwdebug_range(child_pid);
    test_multi_sethwdebug_range_dawr_overlap(child_pid);
   }
  }
 }
}

static int ptrace_hwbreak(void)
{
 pid_t child_pid;
 struct ppc_debug_info dbginfo;
 bool dawr;

 child_pid = fork();
 if (!child_pid) {
  test_workload();
  return 0;
 }

 wait(NULL);

 get_dbginfo(child_pid, &dbginfo);
 SKIP_IF_MSG(dbginfo.num_data_bps == 0, "No data breakpoints present");

 dawr = dawr_present(&dbginfo);
 run_tests(child_pid, &dbginfo, dawr);

 /* Let the child exit first. */
 ptrace(PTRACE_CONT, child_pid, NULL, 0);
 wait(NULL);

 /*
 * Testcases exits immediately with -1 on any failure. If
 * it has reached here, it means all tests were successful.
 */

 return TEST_PASS;
}

int main(int argc, char **argv, char **envp)
{
 is_8xx = mfspr(SPRN_PVR) == PVR_8xx;

 return test_harness(ptrace_hwbreak, "ptrace-hwbreak");
}

Messung V0.5
C=94 H=91 G=92

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© 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