h_segv.c revision 1.4
11.4Skamil/* $NetBSD: h_segv.c,v 1.4 2018/05/22 04:32:56 kamil 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.4Skamil__RCSID("$NetBSD: h_segv.c,v 1.4 2018/05/22 04:32:56 kamil Exp $"); 331.1Schristos 341.4Skamil#include <sys/types.h> 351.4Skamil#include <sys/ptrace.h> 361.1Schristos#include <stdio.h> 371.1Schristos#include <string.h> 381.1Schristos#include <stdlib.h> 391.1Schristos#include <unistd.h> 401.1Schristos#include <signal.h> 411.1Schristos#include <err.h> 421.1Schristos 431.1Schristos// A faulting address 441.1Schristosstatic int *p = (int *) 0xfefefef0; 451.1Schristos 461.1Schristosstatic int flags; 471.1Schristos#define F_RECURSE 1 481.1Schristos#define F_HANDLE 2 491.1Schristos#define F_MASK 4 501.3Skamil#define F_IGNORE 8 511.1Schristos 521.1Schristosstatic struct { 531.1Schristos const char *n; 541.1Schristos int v; 551.1Schristos} nv[] = { 561.1Schristos { "recurse", F_RECURSE }, 571.1Schristos { "handle", F_HANDLE }, 581.1Schristos { "mask", F_MASK }, 591.3Skamil { "ignore", F_IGNORE } 601.1Schristos}; 611.1Schristos 621.4Skamilstatic int sig; 631.4Skamilstatic struct { 641.4Skamil const char *n; 651.4Skamil int v; 661.4Skamil} sn[] = { 671.4Skamil { "segv", SIGSEGV }, 681.4Skamil { "trap", SIGTRAP } 691.4Skamil}; 701.4Skamil 711.1Schristosstatic void 721.1Schristosfoo(int s) 731.1Schristos{ 741.1Schristos char buf[64]; 751.1Schristos int i = snprintf(buf, sizeof(buf), "got %d\n", s); 761.1Schristos write(2, buf, i); 771.4Skamil if (flags & F_RECURSE) { 781.4Skamil if (sig == SIGSEGV) 791.4Skamil *p = 0; 801.4Skamil else if (sig == SIGTRAP) { 811.4Skamil#ifdef PTRACE_BREAKPOINT_ASM 821.4Skamil PTRACE_BREAKPOINT_ASM; 831.4Skamil#else 841.4Skamil /* port me */ 851.4Skamil#endif 861.4Skamil } 871.4Skamil } 881.1Schristos exit(EXIT_SUCCESS); 891.1Schristos} 901.1Schristos 911.1Schristosstatic __dead void 921.1Schristosusage(void) 931.1Schristos{ 941.4Skamil const char *pname = getprogname(); 951.4Skamil 961.4Skamil fprintf(stderr, "Usage: %s recurse|mask|handle|ignore ...\n", pname); 971.1Schristos exit(EXIT_FAILURE); 981.1Schristos} 991.1Schristos 1001.1Schristosint 1011.1Schristosmain(int argc, char *argv[]) 1021.1Schristos{ 1031.1Schristos if (argc == 1) 1041.1Schristos usage(); 1051.1Schristos 1061.1Schristos for (int i = 1; i < argc; i++) { 1071.1Schristos size_t j; 1081.4Skamil for (j = 0; j < __arraycount(nv); j++) { 1091.1Schristos if (strcmp(nv[j].n, argv[i]) == 0) { 1101.1Schristos flags |= nv[j].v; 1111.1Schristos break; 1121.1Schristos } 1131.4Skamil if (strcmp(sn[j].n, argv[i]) == 0) { 1141.4Skamil sig = sn[j].v; 1151.4Skamil break; 1161.4Skamil } 1171.4Skamil } 1181.1Schristos if (j == __arraycount(nv)) 1191.1Schristos usage(); 1201.1Schristos } 1211.1Schristos 1221.4Skamil if (flags == 0 || sig == 0) 1231.1Schristos usage(); 1241.1Schristos 1251.1Schristos if (flags & F_HANDLE) { 1261.1Schristos struct sigaction sa; 1271.1Schristos 1281.1Schristos sa.sa_flags = SA_RESTART; 1291.1Schristos sa.sa_handler = foo; 1301.1Schristos sigemptyset(&sa.sa_mask); 1311.4Skamil if (sigaction(sig, &sa, NULL) == -1) 1321.1Schristos err(EXIT_FAILURE, "sigaction"); 1331.1Schristos } 1341.1Schristos 1351.1Schristos if (flags & F_MASK) { 1361.1Schristos sigset_t set; 1371.1Schristos 1381.1Schristos sigemptyset(&set); 1391.4Skamil sigaddset(&set, sig); 1401.1Schristos if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) 1411.1Schristos err(EXIT_FAILURE, "sigprocmask"); 1421.1Schristos } 1431.1Schristos 1441.3Skamil if (flags & F_IGNORE) { 1451.3Skamil struct sigaction sa; 1461.3Skamil 1471.3Skamil memset(&sa, 0, sizeof(sa)); 1481.3Skamil sa.sa_handler = SIG_IGN; 1491.3Skamil sigemptyset(&sa.sa_mask); 1501.4Skamil if (sigaction(sig, &sa, NULL) == -1) 1511.3Skamil err(EXIT_FAILURE, "sigaction"); 1521.3Skamil } 1531.3Skamil 1541.4Skamil if (sig == SIGSEGV) 1551.4Skamil *p = 1; 1561.4Skamil else if (sig == SIGTRAP) { 1571.4Skamil#ifdef PTRACE_BREAKPOINT_ASM 1581.4Skamil PTRACE_BREAKPOINT_ASM; 1591.4Skamil#else 1601.4Skamil /* port me */ 1611.4Skamil#endif 1621.4Skamil } 1631.1Schristos return EXIT_SUCCESS; 1641.1Schristos} 165