1#!/bin/sh 2 3# 4# Copyright (c) 2014 EMC Corp. 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28 29# panic: pmap active 0xfffff801d22cdae8" seen. 30# Variation of mmap18.sh. 31# http://people.freebsd.org/~pho/stress/log/kostik712.txt 32# Fixed by r271000. 33 34[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 35 36. ../default.cfg 37 38here=`pwd` 39cd /tmp 40sed '1,/^EOF/d' < $here/$0 > mmap19.c 41mycc -o mmap19 -Wall -Wextra -O2 mmap19.c -lpthread || exit 1 42rm -f mmap19.c 43 44daemon sh -c "(cd $here/../testcases/swap; ./swap -t 2m -i 20 -k)" 45rnd=`od -An -N1 -t u1 /dev/random | sed 's/ //g'` 46sleep $((rnd % 10)) 47s=0 48for i in `jot 2`; do 49 /tmp/mmap19 || s=$? 50done 51while pgrep -q swap; do 52 pkill -9 swap 53done 54 55rm -f /tmp/mmap19 /tmp/mmap19.core 56exit $s 57EOF 58#include <sys/types.h> 59#include <sys/mman.h> 60#include <sys/resource.h> 61#include <sys/stat.h> 62#include <sys/time.h> 63#include <sys/wait.h> 64 65#include <err.h> 66#include <errno.h> 67#include <fcntl.h> 68#include <pthread.h> 69#include <pthread_np.h> 70#include <sched.h> 71#include <signal.h> 72#include <stdio.h> 73#include <stdlib.h> 74#include <string.h> 75#include <time.h> 76#include <unistd.h> 77 78#define LOOPS 50 79#define N (128 * 1024 / (int)sizeof(u_int32_t)) 80#define PARALLEL 50 81 82u_int32_t r[N]; 83void *p; 84 85unsigned long 86makearg(void) 87{ 88 unsigned long val; 89 unsigned int i; 90 91 val = arc4random(); 92 i = arc4random() % 100; 93 if (i < 20) 94 val = val & 0xff; 95 if (i >= 20 && i < 40) 96 val = val & 0xffff; 97 if (i >= 40 && i < 60) 98 val = (unsigned long)(r) | (val & 0xffff); 99#if defined(__LP64__) 100 if (i >= 60) { 101 val = (val << 32) | arc4random(); 102 if (i > 80) 103 val = val & 0x00007fffffffffffUL; 104 } 105#endif 106 107 return(val); 108} 109 110void * 111makeptr(void) 112{ 113 unsigned long val; 114 115 if (p != MAP_FAILED && p != NULL) 116 val = (unsigned long)p + arc4random(); 117 else 118 val = makearg(); 119 val = trunc_page(val); 120 121 return ((void *)val); 122} 123 124void * 125tmmap(void *arg __unused) 126{ 127 size_t len; 128 int i, fd; 129 130 pthread_set_name_np(pthread_self(), __func__); 131 len = 1LL * 1024 * 1024 * 1024; 132 133 for (i = 0; i < 100; i++) { 134 if ((fd = open("/dev/zero", O_RDWR)) == -1) 135 err(1,"open()"); 136 137 if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, 138 fd, 0)) != MAP_FAILED) { 139 usleep(100); 140 munmap(p, len); 141 } 142 143 if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 144 0)) != MAP_FAILED) { 145 usleep(100); 146 munmap(p, len); 147 } 148 close(fd); 149 } 150 151 return (NULL); 152} 153 154void * 155tmprotect(void *arg __unused) 156{ 157 void *addr; 158 size_t len; 159 int i, n, prot; 160 161 pthread_set_name_np(pthread_self(), __func__); 162 n = 0; 163 for (i = 0; i < 200; i++) { 164 addr = makeptr(); 165 len = trunc_page(makearg()); 166 prot = makearg(); 167 if (mprotect(addr, len, prot) == 0) 168 n++; 169 usleep(1000); 170 } 171 if (n < 10) 172 fprintf(stderr, "Note: tmprotect() only succeeded %d times.\n", 173 n); 174 175 return (NULL); 176} 177 178void 179test(void) 180{ 181 pthread_t tid[2]; 182 int i, rc; 183 184 if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) 185 errc(1, rc, "tmmap()"); 186 if ((rc = pthread_create(&tid[1], NULL, tmprotect, NULL)) != 0) 187 errc(1, rc, "tmprotect()"); 188 189 for (i = 0; i < 100; i++) { 190 if (fork() == 0) { 191 usleep(10000); 192 _exit(0); 193 } 194 wait(NULL); 195 } 196 197 alarm(120); 198 for (i = 0; i < 2; i++) 199 if ((rc = pthread_join(tid[i], NULL)) != 0) 200 errc(1, rc, "pthread_join(%d)", i); 201 202 _exit(0); 203} 204 205int 206main(void) 207{ 208 pid_t pids[PARALLEL]; 209 time_t start; 210 struct rlimit rl; 211 int e, i, j, status; 212 213 rl.rlim_max = rl.rlim_cur = 0; 214 if (setrlimit(RLIMIT_CORE, &rl) == -1) 215 warn("setrlimit"); 216 217 for (i = 0; i < N; i++) 218 r[i] = arc4random(); 219 220 e = 0; 221 start = time(NULL); 222 for (i = 0; i < LOOPS && e == 0; i++) { 223 for (j = 0; j < PARALLEL; j++) { 224 if ((pids[j] = fork()) == 0) 225 test(); 226 } 227 228 for (j = 0; j < PARALLEL; j++) { 229 if (waitpid(pids[j], &status, 0) != pids[j]) 230 err(1, "waitpid(%d)", pids[j]); 231 if (status != 0 && e == 0 && status != SIGSEGV && status != EFAULT) 232 e = status; 233 } 234 if (time(NULL) - start > 1200) { 235 fprintf(stderr, "Timed out."); 236 break; 237 } 238 } 239 240 return (e); 241} 242