h_segv.c revision 1.1
11.1Schristos/* $NetBSD: h_segv.c,v 1.1 2017/12/07 19:46:40 christos Exp $ */ 21.1Schristos 31.1Schristos/*- 41.1Schristos * Copyright (c) 2017 The NetBSD Foundation, Inc. 51.1Schristos * All rights reserved. 61.1Schristos * 71.1Schristos * This code is derived from software contributed to The NetBSD Foundation 81.1Schristos * by Christos Zoulas. 91.1Schristos * 101.1Schristos * Redistribution and use in source and binary forms, with or without 111.1Schristos * modification, are permitted provided that the following conditions 121.1Schristos * are met: 131.1Schristos * 1. Redistributions of source code must retain the above copyright 141.1Schristos * notice, this list of conditions and the following disclaimer. 151.1Schristos * 2. Redistributions in binary form must reproduce the above copyright 161.1Schristos * notice, this list of conditions and the following disclaimer in the 171.1Schristos * documentation and/or other materials provided with the distribution. 181.1Schristos * 191.1Schristos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.1Schristos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.1Schristos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.1Schristos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.1Schristos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.1Schristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.1Schristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.1Schristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.1Schristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.1Schristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.1Schristos * POSSIBILITY OF SUCH DAMAGE. 301.1Schristos */ 311.1Schristos#include <sys/cdefs.h> 321.1Schristos__RCSID("$NetBSD: h_segv.c,v 1.1 2017/12/07 19:46:40 christos Exp $"); 331.1Schristos 341.1Schristos#include <stdio.h> 351.1Schristos#include <string.h> 361.1Schristos#include <stdlib.h> 371.1Schristos#include <unistd.h> 381.1Schristos#include <signal.h> 391.1Schristos#include <err.h> 401.1Schristos 411.1Schristos// A faulting address 421.1Schristosstatic int *p = (int *) 0xfefefef0; 431.1Schristos 441.1Schristosstatic int flags; 451.1Schristos#define F_RECURSE 1 461.1Schristos#define F_HANDLE 2 471.1Schristos#define F_MASK 4 481.1Schristos 491.1Schristosstatic struct { 501.1Schristos const char *n; 511.1Schristos int v; 521.1Schristos} nv[] = { 531.1Schristos { "recurse", F_RECURSE }, 541.1Schristos { "handle", F_HANDLE }, 551.1Schristos { "mask", F_MASK }, 561.1Schristos}; 571.1Schristos 581.1Schristosstatic void 591.1Schristosfoo(int s) 601.1Schristos{ 611.1Schristos char buf[64]; 621.1Schristos int i = snprintf(buf, sizeof(buf), "got %d\n", s); 631.1Schristos write(2, buf, i); 641.1Schristos if (flags & F_RECURSE) 651.1Schristos *p = 0; 661.1Schristos exit(EXIT_SUCCESS); 671.1Schristos} 681.1Schristos 691.1Schristosstatic __dead void 701.1Schristosusage(void) 711.1Schristos{ 721.1Schristos fprintf(stderr, "Usage: %s recurse|mask|unhandle ...\n", getprogname()); 731.1Schristos exit(EXIT_FAILURE); 741.1Schristos} 751.1Schristos 761.1Schristosint 771.1Schristosmain(int argc, char *argv[]) 781.1Schristos{ 791.1Schristos if (argc == 1) 801.1Schristos usage(); 811.1Schristos 821.1Schristos for (int i = 1; i < argc; i++) { 831.1Schristos size_t j; 841.1Schristos for (j = 0; j < __arraycount(nv); j++) 851.1Schristos if (strcmp(nv[j].n, argv[i]) == 0) { 861.1Schristos flags |= nv[j].v; 871.1Schristos break; 881.1Schristos } 891.1Schristos if (j == __arraycount(nv)) 901.1Schristos usage(); 911.1Schristos } 921.1Schristos 931.1Schristos if (flags == 0) 941.1Schristos usage(); 951.1Schristos 961.1Schristos if (flags & F_HANDLE) { 971.1Schristos struct sigaction sa; 981.1Schristos 991.1Schristos sa.sa_flags = SA_RESTART; 1001.1Schristos sa.sa_handler = foo; 1011.1Schristos sigemptyset(&sa.sa_mask); 1021.1Schristos if (sigaction(SIGSEGV, &sa, NULL) == -1) 1031.1Schristos err(EXIT_FAILURE, "sigaction"); 1041.1Schristos } 1051.1Schristos 1061.1Schristos if (flags & F_MASK) { 1071.1Schristos sigset_t set; 1081.1Schristos 1091.1Schristos sigemptyset(&set); 1101.1Schristos sigaddset(&set, SIGSEGV); 1111.1Schristos if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) 1121.1Schristos err(EXIT_FAILURE, "sigprocmask"); 1131.1Schristos } 1141.1Schristos 1151.1Schristos *p = 1; 1161.1Schristos return EXIT_SUCCESS; 1171.1Schristos} 118