Index: user/pho/stress2/misc/db.sh =================================================================== --- user/pho/stress2/misc/db.sh (revision 291420) +++ user/pho/stress2/misc/db.sh (revision 291421) @@ -1,177 +1,177 @@ #!/bin/sh # # Copyright (c) 2015 EMC Corp. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Demonstrate resource starvation using msync(2). . ../default.cfg dir=/tmp odir=`pwd` cd $dir sed '1,/^EOF/d' < $odir/$0 > $dir/db.c mycc -o db -Wall -Wextra -O0 -g db.c -lpthread || exit 1 rm -f db.c cd $odir -diskimage=/var/tmp/diskimage dd if=/dev/zero of=$diskimage bs=1m count=10 2>&1 | \ egrep -v "records|transferred" /tmp/db $diskimage & start=`date '+%s'` ls -l $diskimage > /dev/null [ `date '+%s'` -gt $((start + 90)) ] && { fail="yes"; echo FAIL; } wait rm -f /tmp/db $diskimage [ "$fail" = "yes" ] && exit 1 || exit 0 EOF #include #include #include #include #include #include #include #include #ifdef __FreeBSD__ #include #define __NP__ #endif #include #include #include #include #include pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; size_t len; void *p; int wthreads; #define BZ 128 /* buffer size */ #define RUNTIME 180 /* runtime for test */ #define RTHREADS 64 /* reader threads */ #define WTHREADS 64 /* writer threads */ void * wt(void *arg __unused) { time_t start; int64_t pos; void *c; + int r; char buf[BZ]; #ifdef __NP__ pthread_set_name_np(pthread_self(), __func__); #endif - if (pthread_mutex_lock(&mutex) == -1) - err(1, "pthread_mutex_lock"); + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); wthreads++; - if (pthread_mutex_unlock(&mutex) == -1) - err(1, "pthread_mutex_unlock"); + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); start = time(NULL); while (time(NULL) - start < RUNTIME) { pos = arc4random() % (len / BZ); pos = pos * BZ; c = p + pos; bcopy(buf, c, BZ); c = (void *)trunc_page((unsigned long)c); if (msync((void *)c, round_page(BZ), MS_SYNC) == -1) err(1, "msync(%p)", c); usleep(10000 + arc4random() % 1000); } - if (pthread_mutex_lock(&mutex) == -1) - err(1, "pthread_mutex_lock"); + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); wthreads--; - if (pthread_mutex_unlock(&mutex) == -1) - err(1, "pthread_mutex_unlock"); + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); return (NULL); } void * rt(void *arg __unused) { int64_t pos; char buf[BZ], *c; #ifdef __NP__ pthread_set_name_np(pthread_self(), __func__); #endif c = p; do { pos = arc4random() % (len / BZ); pos = pos * BZ; bcopy(&c[pos], buf, BZ); usleep(10000 + arc4random() % 1000); } while (wthreads != 0); return (NULL); } int main(int argc, char *argv[]) { pthread_t cp[RTHREADS + WTHREADS]; struct stat st; int fd, i, j, rc; if (argc != 2) errx(1, "Usage: %s ", argv[0]); if ((fd = open(argv[1], O_RDWR)) == -1) err(1, "open %s", argv[1]); if (fstat(fd, &st) == -1) err(1, "stat"); len = round_page(st.st_size); p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if ((void *)p == MAP_FAILED) err(1, "mmap"); i = 0; for (j = 0; j < WTHREADS; j++) { if ((rc = pthread_create(&cp[i++], NULL, wt, NULL)) != 0) errc(1, rc, "pthread_create()"); } usleep(100); for (j = 0; j < RTHREADS; j++) { if ((rc = pthread_create(&cp[i++], NULL, rt, NULL)) != 0) errc(1, rc, "pthread_create()"); } for (j = 0; j < RTHREADS + WTHREADS; j++) pthread_join(cp[--i], NULL); return (0); } Index: user/pho/stress2/misc/devfd.sh =================================================================== --- user/pho/stress2/misc/devfd.sh (revision 291420) +++ user/pho/stress2/misc/devfd.sh (revision 291421) @@ -1,131 +1,132 @@ #!/bin/sh # # Copyright (c) 2011 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # "panic: vn_lock 0xc65b5828: zero hold count" seen. # Originally found by the iknowthis test suite # by Tavis Ormandy # Fixed by r227952 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > devfd.c rm -f /tmp/devfd mycc -o devfd -Wall -Wextra -O2 -g devfd.c -lpthread || exit 1 rm -f devfd.c mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart mdconfig -a -t swap -s 1g -u $mdstart || exit 1 bsdlabel -w md$mdstart auto newfs $newfs_flags md${mdstart}$part > /dev/null mount /dev/md${mdstart}$part $mntpoint chmod 777 $mntpoint su $testuser -c "(cd $mntpoint; /tmp/devfd)" while mount | grep $mntpoint | grep -q /dev/md; do umount $mntpoint || sleep 1 done mdconfig -d -u $mdstart rm -f /tmp/devfd exit EOF #include #include #include #include #include #include #include #include #include int fd[3], fd2[3]; void * thr1(void *arg __unused) { int i, j; char path[80]; for (i = 0; i < 100000; i++) { for (j = 0; j < 3; j++) { if (fd[j] != -1) close(fd[j]); sprintf(path, "fx%d", j); fd[j] = open(path, O_RDWR | O_CREAT, 0640); } } return (0); } void * thr2(void *arg __unused) { int i, j; char path[80]; for (i = 0; i < 100000; i++) { for (j = 0; j < 3; j++) { if (fd2[j] != -1) close(fd2[j]); sprintf(path, "/dev/fd/%d", j); if ((fd2[j] = open(path, O_RDONLY)) != -1) fchflags(fd2[j], UF_NODUMP); } } return (0); } int main(void) { pthread_t p1, p2; + int r; close(0); close(1); close(2); - if (pthread_create(&p1, NULL, thr1, NULL) != 0) - err(1, "pthread_create"); - if (pthread_create(&p2, NULL, thr2, NULL) != 0) - err(1, "pthread_create"); + if ((r = pthread_create(&p1, NULL, thr1, NULL)) != 0) + errc(1, r, "pthread_create"); + if ((r = pthread_create(&p2, NULL, thr2, NULL)) != 0) + errc(1, r, "pthread_create"); pthread_join(p1, NULL); pthread_join(p2, NULL); return (0); } Index: user/pho/stress2/misc/devfs2.sh =================================================================== --- user/pho/stress2/misc/devfs2.sh (revision 291420) +++ user/pho/stress2/misc/devfs2.sh (revision 291421) @@ -1,110 +1,110 @@ #!/bin/sh # # Copyright (c) 2008 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Stopped at devfs_open+0x23f: pushl 0x14(%ebx) # db> where # Tracing pid 46017 tid 100350 td 0xc4c08510 # devfs_open(e6d06a10) at devfs_open+0x23f # VOP_OPEN_APV(c09edda0,e6d06a10) at VOP_OPEN_APV+0x9b # vn_open_cred(e6d06b78,e6d06c78,0,c4883900,3,...) at vn_open_cred+0x41e # vn_open(e6d06b78,e6d06c78,0,3) at vn_open+0x1e # kern_open(c4c08510,8048887,0,1,0,...) at kern_open+0xb7 # open(c4c08510,e6d06d00) at open+0x18 # syscall(e6d06d38) at syscall+0x252 # Test scenario by kib@freebsd.org . ../default.cfg odir=`pwd` dir=/tmp cd $dir sed '1,/^EOF/d' < $odir/$0 > $dir/devfs2.c mycc -o devfs2 -Wall devfs2.c -lthr rm -f devfs2.c ./devfs2 rm devfs2 exit EOF #include #include #include #include #include #include #include #include void * thr1(void *arg) { int fd; int i; for (i = 0; i < 1024; i++) { if ((fd = open("/dev/zero", O_RDONLY)) == -1) perror("open /dev/zero"); close(fd); } return (0); } void * thr2(void *arg) { int i; for (i = 0; i < 1024; i++) close(3); return (0); } int main() { pthread_t threads[2]; int i; int r; if ((r = pthread_create(&threads[0], NULL, thr1, 0)) != 0) err(1, "pthread_create(): %s\n", strerror(r)); if ((r = pthread_create(&threads[1], NULL, thr2, 0)) != 0) err(1, "pthread_create(): %s\n", strerror(r)); for (i = 0; i < 2; i++) - if (pthread_join(threads[i], NULL) != 0) - err(1, "pthread_join(%d)", i); + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); return (0); } Index: user/pho/stress2/misc/f_offset.sh =================================================================== --- user/pho/stress2/misc/f_offset.sh (revision 291420) +++ user/pho/stress2/misc/f_offset.sh (revision 291421) @@ -1,162 +1,162 @@ #!/bin/sh # # Copyright (c) 2012 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Problem seen with atomic assignment of f_offset. Fixed in r238029. # Test scenario by kib@ . ../default.cfg here=`pwd` cd /tmp sed '1,/^EOF/d' < $here/$0 > f_offset.c mycc -o f_offset -Wall -Wextra -O2 f_offset.c -lpthread rm -f f_offset.c /tmp/f_offset rm -f /tmp/f_offset exit 0 EOF /* Description by kib: To really exercise the race conditions, all the following items must be fulfilled simultaneously: 1. you use 32bit host, i.e. i386 2. you operate on the file offsets larger than 4GB (but see below) 3. there are several threads or processes that operate on the same file descriptor simultaneously. Please note that the normal fork(2) causes file descriptor table copy, so only rfork(2) call with RFFDG flag unset causes sharing. Or, multi-threading can be used. */ #include #include #include #include #include #include #include #include int errors, fd; char file[128]; #define START 0x100000000ULL #define N 1000000 void * t1(void *arg __unused) { int i; off_t offset; offset = START + 2; for (i = 0; i < N; i++) { if (lseek(fd, offset, SEEK_SET) == -1) err(1, "lseek error"); } return (0); } void * t2(void *arg __unused) { int i; off_t offset; offset = 1; for (i = 0; i < N; i++) { if (lseek(fd, offset, SEEK_SET) == -1) err(1, "lseek error"); } return (0); } void * t3(void *arg __unused) { int i; off_t offset; offset = 1; for (i = 0; i < N; i++) { if ((offset = lseek(fd, 0, SEEK_CUR)) == -1) err(1, "lseek error"); if (offset != 1 && offset != START + 2) fprintf(stderr, "FAIL #%d offset = %10jd (0x%09jx)\n", errors++, offset, offset); } return (0); } int main(void) { pthread_t threads[3]; int r; int i; off_t offset; snprintf(file, sizeof(file), "file.%06d", getpid()); if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) err(1, "%s", file); offset = 1; if (lseek(fd, offset, SEEK_SET) == -1) err(1, "lseek error"); for (i = 0; i < 20 && errors < 10; i++) { if ((r = pthread_create(&threads[0], NULL, t1, 0)) != 0) - err(1, "pthread_create(): %s\n", strerror(r)); + errc(1, r, "pthread_create()"); if ((r = pthread_create(&threads[1], NULL, t2, 0)) != 0) - err(1, "pthread_create(): %s\n", strerror(r)); + errc(1, r, "pthread_create()"); if ((r = pthread_create(&threads[2], NULL, t3, 0)) != 0) - err(1, "pthread_create(): %s\n", strerror(r)); + errc(1, r, "pthread_create()"); - if (pthread_join(threads[0], NULL) != 0) - err(1, "pthread_join(%d)", 0); - if (pthread_join(threads[1], NULL) != 0) - err(1, "pthread_join(%d)", 1); - if (pthread_join(threads[2], NULL) != 0) - err(1, "pthread_join(%d)", 2); + if ((r = pthread_join(threads[0], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 0); + if ((r = pthread_join(threads[1], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 1); + if ((r = pthread_join(threads[2], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 2); } close(fd); if (unlink(file) == -1) err(3, "unlink(%s)", file); return (0); } Index: user/pho/stress2/misc/kevent2.sh =================================================================== --- user/pho/stress2/misc/kevent2.sh (revision 291420) +++ user/pho/stress2/misc/kevent2.sh (revision 291421) @@ -1,176 +1,176 @@ #!/bin/sh # # Copyright (c) 2008 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > kevent2.c mycc -o kevent2 -Wall kevent2.c -pthread rm -f kevent2.c cd $RUNDIR for i in `jot 10`; do for j in `jot 12`; do /tmp/kevent2 > /dev/null 2>&1 & done - for j in `jot 12`; do - wait - done + wait done rm -f /tmp/kevent2 exit EOF #include #include #include #include #include #include #include #include #include pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; static int waiting; static int fd1[2]; static int fd2[2]; static int fd3[2]; void * thr1(void *arg) { - int n; + int n, r; int kq = -1; struct kevent ev[3]; struct timespec ts; if ((kq = kqueue()) < 0) err(1, "kqueue(). %s:%d", __FILE__, __LINE__); n = 0; EV_SET(&ev[n], fd1[1], EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); n++; EV_SET(&ev[n], fd2[1], EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); n++; EV_SET(&ev[n], fd3[1], EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); n++; if (kevent(kq, ev, n, NULL, 0, NULL) < 0) err(1, "kevent(). %s:%d", __FILE__, __LINE__); - if (pthread_mutex_lock(&mutex) == -1) - err(1, "pthread_mutex_lock"); + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); waiting = 0; - if (pthread_cond_signal(&cond) == -1) - err(1, "pthread_cond_signal"); - if (pthread_mutex_unlock(&mutex) == -1) - err(1, "pthread_mutex_unlock"); + if ((r = pthread_cond_signal(&cond)) != 0) + errc(1, r, "pthread_cond_signal"); + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); n = 0; EV_SET(&ev[n], fd1[1], EVFILT_WRITE, EV_DELETE, 0, 0, 0); n++; ts.tv_sec = 0; ts.tv_nsec = 0; if (kevent(kq, ev, n, NULL, 0, &ts) < 0) err(1, "kevent(). %s:%d", __FILE__, __LINE__); close(kq); // printf("%s:%d\n", __FILE__, __LINE__); fflush(stdout); close(fd1[1]); close(fd2[1]); close(fd3[1]); return (0); } void * thr2(void *arg) { - if (pthread_mutex_lock(&mutex) == -1) - err(1, "pthread_mutex_lock"); + int r; + + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); while (waiting == 1) { - if (pthread_cond_wait(&cond, &mutex) == -1) - err(1, "pthread_cond_wait"); + if ((r = pthread_cond_wait(&cond, &mutex)) != 0) + errc(1, r, "pthread_cond_wait"); } - if (pthread_mutex_unlock(&mutex) == -1) - err(1, "pthread_mutex_unlock"); + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); // printf("%s:%d\n", __FILE__, __LINE__); fflush(stdout); close(fd1[0]); close(fd2[0]); close(fd3[0]); return (0); } int main(int argc, char **argv) { pthread_t threads[2]; int r; int i; for (i = 0; i < 1000; i++) { waiting = 1; // printf("%s:%d\n", __FILE__, __LINE__); fflush(stdout); if (pipe(fd1) == -1) err(1, "pipe()"); if (pipe(fd2) == -1) err(1, "pipe()"); if (pipe(fd3) == -1) err(1, "pipe()"); - if (pthread_mutex_init(&mutex, 0) == -1) - err(1, "pthread_mutex_init"); - if (pthread_cond_init(&cond, NULL) == -1) - err(1, "pthread_cond_init"); + if ((r = pthread_mutex_init(&mutex, 0)) != 0) + errc(1, r, "pthread_mutex_init"); + if ((r = pthread_cond_init(&cond, NULL)) != 0) + errc(1, r, "pthread_cond_init"); if ((r = pthread_create(&threads[0], NULL, thr1, 0)) != 0) - err(1, "pthread_create(): %s\n", strerror(r)); + errc(1, r, "pthread_create()"); if ((r = pthread_create(&threads[1], NULL, thr2, 0)) != 0) - err(1, "pthread_create(): %s\n", strerror(r)); + errc(1, r, "pthread_create()"); - if (pthread_join(threads[0], NULL) != 0) - err(1, "pthread_join(%d)", 0); - if (pthread_join(threads[1], NULL) != 0) - err(1, "pthread_join(%d)", 1); - if (pthread_mutex_destroy(&mutex) == -1) - err(1, "pthread_mutex_destroy"); - if (pthread_cond_destroy(&cond) == -1) - err(1, "pthread_condattr_destroy"); + if ((r = pthread_join(threads[0], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 0); + if ((r = pthread_join(threads[1], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 1); + if ((r = pthread_mutex_destroy(&mutex)) != 0) + errc(1, r, "pthread_mutex_destroy"); + if ((r = pthread_cond_destroy(&cond)) != 0) + errc(1, r, "pthread_condattr_destroy"); } return (0); } Index: user/pho/stress2/misc/kinfo3.sh =================================================================== --- user/pho/stress2/misc/kinfo3.sh (revision 291420) +++ user/pho/stress2/misc/kinfo3.sh (revision 291421) @@ -1,194 +1,194 @@ #!/bin/sh # # Copyright (c) 2008 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Test scenario by marcus@freebsd.org and kib@freebsd.org [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > kinfo3.c mycc -o kinfo3 -Wall kinfo3.c -lutil -pthread rm -f kinfo3.c mount | grep -q procfs || mount -t procfs procfs /procfs for i in `jot 30`; do for j in `jot 5`; do /tmp/kinfo3 & done for j in `jot 5`; do wait done done rm -f /tmp/kinfo3 exit EOF #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include char buf[8096]; static volatile sig_atomic_t more; void handler(int i) { more = 0; } void * thr(void *arg) { int fd; if ((fd = open("/proc/curproc/mem", O_RDONLY)) == -1) err(1, "open(/proc/curproc/mem)"); close(fd); return (0); } /* Stir /dev/proc */ int churning(void) { int i; pid_t r; int status; pthread_t threads[5]; while(more) { r = fork(); if (r == 0) { for (i = 0; i < 5; i++) { if ((r = pthread_create(&threads[i], NULL, thr, 0)) != 0) - err(1, "pthread_create(): %s\n", strerror(r)); + errc(1, r, "pthread_create()"); } for (i = 0; i < 5; i++) { - if (pthread_join(threads[i], NULL) != 0) - err(1, "pthread_join(%d)", 0); + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); } bzero(buf, sizeof(buf)); exit(0); } if (r < 0) { perror("fork"); exit(2); } wait(&status); } exit(0); } /* Get files for each proc */ void list(void) { struct kinfo_file *freep, *kif; struct kinfo_vmentry *freep_vm; long i, j; int cnt, name[4]; struct kinfo_proc *kipp; size_t len; name[0] = CTL_KERN; name[1] = KERN_PROC; name[2] = KERN_PROC_PROC; len = 0; if (sysctl(name, 3, NULL, &len, NULL, 0) < 0) err(-1, "sysctl: kern.proc.all"); kipp = malloc(len); if (kipp == NULL) err(1, "malloc"); if (sysctl(name, 3, kipp, &len, NULL, 0) < 0) { free(kipp); // warn("sysctl: kern.proc.all"); return; } for (i = 0; i < len / sizeof(*kipp); i++) { /* The test starts here */ freep = kinfo_getfile(kipp[i].ki_pid, &cnt); for (j = 0; j < cnt && freep; j++) { kif = &freep[j]; // printf("%d : %s\n", kif->kf_fd, kif->kf_path); } free(freep); freep_vm = kinfo_getvmmap(kipp[i].ki_pid, &cnt); free(freep_vm); /* End test */ } free(kipp); } int main(int argc, char **argv) { pid_t r; signal(SIGALRM, handler); alarm(30); more = 1; if ((r = fork()) == 0) { alarm(30); while(more) churning(); } if (r < 0) { perror("fork"); exit(2); } while(more) list(); return (0); } Index: user/pho/stress2/misc/mmap2.sh =================================================================== --- user/pho/stress2/misc/mmap2.sh (revision 291420) +++ user/pho/stress2/misc/mmap2.sh (revision 291421) @@ -1,178 +1,179 @@ #!/bin/sh # # Copyright (c) 2009 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Stress mmap by having at most 100 threads mapping random areas within # a 100 Mb range. # Test scenario by kib@ . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > mmap2.c mycc -o mmap2 -Wall -g mmap2.c -lpthread rm -f mmap2.c -for i in `jot 10`; do +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 600 ]; do ./mmap2 done rm -f ./mmap2 exit EOF #include #include #include #include #include #include #include #include #include #include #include #include #define THREADS 100 #define STARTADDR 0x50000000U #define ADRSPACE 0x06400000U /* 100 Mb */ static void work(int nr) { int fd, m; void *p; size_t left, len; char path[128]; p = (void *)STARTADDR + trunc_page(arc4random() % ADRSPACE); left = ADRSPACE - (size_t)p + STARTADDR; len = trunc_page(arc4random() % left) + PAGE_SIZE; fd = -1; if (arc4random() % 100 < 90) sprintf(path, "/tmp/mmap.%06d.%04d", getpid(), nr); else sprintf(path, "/dev/zero"); if (arc4random() % 2 == 0) { if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1) err(1,"open()"); if (ftruncate(fd, len) == -1) err(1, "ftruncate"); if (arc4random() % 2 == 0) { if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) { if (errno == ENOMEM) return; err(1, "mmap()"); } } else { if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)) == MAP_FAILED) { if (errno == ENOMEM) return; err(1, "mmap()"); } } if (fd > 0 && strcmp(path, "/dev/zero")) if (unlink(path) == -1) err(1, "unlink(%s)", path); } else { if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0)) == MAP_FAILED) { if (errno == ENOMEM) return; err(1, "mmap()"); } strcpy(path, "anon"); } #if 0 printf("nr = %d, %-14s, start = %p, end = %p, len = 0x%08x, (%5d pages)\n", nr, path, p, p + len, len, len>>PAGE_SHIFT); #endif *(int *)p = 1; if (arc4random() % 2 == 0) { m = arc4random() % 10; if (madvise(p, len, m) == -1) warn("madvise(%p, %zd, %d)", p, len, m); } if (arc4random() %2 == 0) if (mprotect(p, trunc_page(arc4random() % len), PROT_READ) == -1 ) err(1, "mprotect failed with error:"); if (arc4random() % 2 == 0) { if (arc4random() %2 == 0) { if (msync(p, 0, MS_SYNC) == -1) err(1, "msync(%p)", p); } else { if (msync(p, 0, MS_INVALIDATE) == -1) err(1, "msync(%p)", p); } } if (munmap(p, len) == -1) err(1, "munmap(%p)", p); close(fd); } void * thr(void *arg) { int i; for (i = 0; i < 512; i++) { work(*(int *)arg); } return (0); } int main(int argc, char **argv) { pthread_t threads[THREADS]; int nr[THREADS]; int i, n, r; // printf("Address start 0x%x, address end 0x%x, pages %d\n", // STARTADDR, STARTADDR + ADRSPACE, ADRSPACE>>PAGE_SHIFT); n = arc4random() % THREADS + 1; for (i = 0; i < n; i++) { nr[i] = i; if ((r = pthread_create(&threads[i], NULL, thr, (void *)&nr[i])) != 0) - err(1, "pthread_create(): %s\n", strerror(r)); + errc(1, r, "pthread_create()"); } for (i = 0; i < n; i++) { - if (pthread_join(threads[i], NULL) != 0) - err(1, "pthread_join(%d)", i); + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); } return (0); } Index: user/pho/stress2/misc/mmap3.sh =================================================================== --- user/pho/stress2/misc/mmap3.sh (revision 291420) +++ user/pho/stress2/misc/mmap3.sh (revision 291421) @@ -1,169 +1,169 @@ #!/bin/sh # # Copyright (c) 2009 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Variation of mmap2.sh with focus on random arguments for mprotect() # https://people.freebsd.org/~pho/stress/log/kostik209.txt . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > mmap3.c mycc -o mmap3 -Wall mmap3.c -lpthread || exit 1 rm -f mmap3.c start=`date '+%s'` while [ `date '+%s'` -lt $((start + 5 * 60)) ]; do ./mmap3 done echo "Expect Segmentation faults" start=`date '+%s'` while [ `date '+%s'` -lt $((start + 5 * 60)) ]; do ./mmap3 random done rm -f mmap3 mmap3.core /tmp/mmap.0* exit EOF /* Stress mmap by having max 100 threads mapping random areas within a 100 Mb range. */ #include #include #include #include #include #include #include #include #include #include #include #include #define THREADS 100 #define STARTADDR 0x50000000U #define ADRSPACE 0x06400000U /* 100 Mb */ static int ra; void trash(void *p) { unsigned long v; mprotect(p, 0x570e3d38, 0x2c8fd54f); if (ra) { v = arc4random(); #if defined(__LP64__) v = v << 32 | arc4random(); #endif madvise((void *)v, arc4random(), arc4random()); mprotect((void *)v, arc4random(), arc4random()); msync((void *)v, arc4random(), arc4random()); } } void work(int nr) { int fd, m; void *p; size_t len; char path[128]; p = (void *)STARTADDR; len = ADRSPACE; sprintf(path, "/tmp/mmap.%06d.%04d", getpid(), nr); if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1) err(1,"open()"); if (ftruncate(fd, len) == -1) err(1, "ftruncate"); if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) { if (errno == ENOMEM) return; err(1, "mmap()"); } if (unlink(path) == -1) err(1, "unlink(%s)", path); trash(p); m = arc4random() % 10; if (madvise(p, len, m) == -1) warn("madvise(%p, %zd, %d)", p, len, m); if (mprotect(p, trunc_page(arc4random() % len), PROT_READ) == -1 ) err(1, "mprotect failed with error:"); if (msync(p, 0, MS_SYNC) == -1) err(1, "msync(%p)", p); if (munmap(p, len) == -1) err(1, "munmap(%p)", p); close(fd); } void * thr(void *arg) { int i; for (i = 0; i < 512; i++) { work(*(int *)arg); } return (0); } int main(int argc, char **argv) { pthread_t threads[THREADS]; int nr[THREADS]; int i, n, r; n = arc4random() % 14 + 5; ra = argc != 1; // printf("Address start 0x%x, address end 0x%x, pages %d, n %d\n", // STARTADDR, STARTADDR + ADRSPACE, ADRSPACE>>PAGE_SHIFT, n); for (i = 0; i < n; i++) { nr[i] = i; if ((r = pthread_create(&threads[i], NULL, thr, (void *)&nr[i])) != 0) - err(1, "pthread_create(): %s\n", strerror(r)); + errc(1, r, "pthread_create()"); } for (i = 0; i < n; i++) { - if (pthread_join(threads[i], NULL) != 0) - err(1, "pthread_join(%d)", i); + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); } return (0); } Index: user/pho/stress2/misc/pthread5.sh =================================================================== --- user/pho/stress2/misc/pthread5.sh (revision 291420) +++ user/pho/stress2/misc/pthread5.sh (revision 291421) @@ -1,123 +1,123 @@ #!/bin/sh # # Copyright (c) 2014 EMC Corp. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Stress shchan allocations. . ../default.cfg [ `swapinfo | wc -l` -eq 1 ] && exit 0 # kstack allocation failed here=`pwd` cd /tmp sed '1,/^EOF/d' < $here/$0 > pthread5.c mycc -o pthread5 -Wall -Wextra -O2 pthread5.c -lpthread || exit 1 rm -f pthread5.c /tmp/pthread5 rm -f /tmp/pthread5 exit 0 EOF #include #include #include #include #include #include #include #include #include #include #define ITER 2 #define PARALLEL 1000 #define THREADS 100 pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static void * nicethreads(void *data __unused) { struct timespec ts; struct timeval tp; pthread_mutex_lock(&mutex); gettimeofday(&tp, NULL); ts.tv_sec = tp.tv_sec; ts.tv_nsec = tp.tv_usec * 1000; ts.tv_sec += 30; pthread_cond_timedwait(&cond, &mutex, &ts); pthread_mutex_unlock(&mutex); return (NULL); } int test(void) { int num_thread = THREADS; pthread_t tid[num_thread]; int i, iter, rc; for (iter = 0; iter < ITER; iter++) { for (i = 0; i < num_thread; i++) { if ((rc = pthread_create(&tid[i], NULL, nicethreads, - NULL)) == -1) + NULL)) != 0) errc(1, rc, "pthread_create"); } usleep(20000); for (i = 0; i < num_thread; i++) { rc = pthread_mutex_lock(&mutex); rc = pthread_cond_signal(&cond); rc = pthread_mutex_unlock(&mutex); } for (i = 0; i < num_thread; i++) - if ((rc = pthread_join(tid[i], NULL)) == -1) + if ((rc = pthread_join(tid[i], NULL)) != 0) errc(1, rc, "pthread_join"); } _exit(0); } int main(void) { int i; for (i = 0; i < PARALLEL; i++) if (fork() == 0) test(); for (i = 0; i < PARALLEL; i++) wait(NULL); return (0); } Index: user/pho/stress2/misc/pthread9.sh =================================================================== --- user/pho/stress2/misc/pthread9.sh (revision 291420) +++ user/pho/stress2/misc/pthread9.sh (revision 291421) @@ -1,185 +1,185 @@ #!/bin/sh # # Copyright (c) 2015 EMC Corp. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Thread suspend deadlock seen: # https://people.freebsd.org/~pho/stress/log/pthread9.txt # Test scenario by Conrad Meyer. # Fixed by r283320. [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 . ../default.cfg here=`pwd` cd /tmp sed '1,/^EOF/d' < $here/$0 > pthread9.c mycc -o pthread9 -Wall -Wextra -O2 pthread9.c -lpthread || exit 1 rm -f pthread9.c status=0 if ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1; then mount -t nfs -o nfsv3,tcp,nolockd,retrycnt=3,intr $nfs_export \ $mntpoint || exit 1 sleep .5 (cd $mntpoint; /tmp/pthread9) & sleep 200 if pgrep -q pthread9; then echo FAIL procstat -k `pgrep pthread9 | grep -v $!` status=1 fi umount -f $mntpoint wait fi rm -f /tmp/pthread9 exit $status EOF #include #include #include #include #include #include #ifdef __FreeBSD__ #include #define __NP__ #endif #include #include #include #include #include #define LOOPS 50 #define RUNTIME 180 volatile u_int go; int fd; char file[] = "pthread9.file"; static void * t1(void *data __unused) { int i; #ifdef __NP__ pthread_set_name_np(pthread_self(), __func__); #endif while (go == 0) pthread_yield(); atomic_add_int(&go, 1); for (i = 0; i < 100; i++) if (ftruncate(fd, 0) == -1) err(1, "truncate"); return (NULL); } static void * t2(void *data __unused) { int i; #ifdef __NP__ pthread_set_name_np(pthread_self(), __func__); #endif while (go == 0) pthread_yield(); atomic_add_int(&go, 1); for (i = 0; i < 100; i++) if (ftruncate(fd, 0) == -1) err(1, "truncate"); return (NULL); } static void * t3(void *data __unused) { #ifdef __NP__ pthread_set_name_np(pthread_self(), __func__); #endif while (go != 3) pthread_yield(); abort(); return (NULL); } int test(void) { pthread_t tid[3]; int i, rc; go = 0; - if ((rc = pthread_create(&tid[0], NULL, t1, NULL)) == -1) + if ((rc = pthread_create(&tid[0], NULL, t1, NULL)) != 0) errc(1, rc, "pthread_create"); - if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) == -1) + if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) != 0) errc(1, rc, "pthread_create"); - if ((rc = pthread_create(&tid[2], NULL, t3, NULL)) == -1) + if ((rc = pthread_create(&tid[2], NULL, t3, NULL)) != 0) errc(1, rc, "pthread_create"); usleep(200); atomic_add_int(&go, 1); for (i = 0; i < 3; i++) { - if ((rc = pthread_join(tid[i], NULL)) == -1) + if ((rc = pthread_join(tid[i], NULL)) != 0) errc(1, rc, "pthread_join"); } _exit(0); } int main(void) { time_t start; if ((fd = open(file, O_RDWR | O_CREAT, 0644)) == -1) err(1, "open(%s)", file); start = time(NULL); while (time(NULL) - start < RUNTIME) { if (fork() == 0) test(); wait(NULL); } close(fd); unlink(file); return (0); } Index: user/pho/stress2/misc/truss.sh =================================================================== --- user/pho/stress2/misc/truss.sh (revision 291420) +++ user/pho/stress2/misc/truss.sh (revision 291421) @@ -1,130 +1,130 @@ #!/bin/sh # # Copyright (c) 2015 EMC Corp. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # truss(1) of a multithreaded program. # FAIL # 0 90968 90933 0 52 0 6028 0 wait IW+ 1 0:00,00 truss /tmp/ttruss # 0 90970 90968 0 52 0 6436 1560 uwrlck IX+ 1 0:00,00 /tmp/ttruss # $ procstat -k 90970 # PID TID COMM TDNAME KSTACK # 90970 101244 ttruss - mi_switch sleepq_switch # sleepq_catch_signals sleepq_wait_sig _sleep umtxq_sleep # do_rw_wrlock __umtx_op_rw_wrlock syscall Xint0x80_syscall # $ # Only seen during testing of a WiP ptrace(2) patch. . ../default.cfg dir=/tmp odir=`pwd` cd $dir sed '1,/^EOF/d' < $odir/$0 > $dir/ttruss.c mycc -o ttruss -Wall -Wextra -O0 -g ttruss.c -lpthread || exit 1 rm -f ttruss.c # VM pressure is not mandatory, but shortens the time to failure. daemon sh -c \ "(cd $odir/../testcases/swap; ./swap -t 6m -i 20 -k -l 100)" > \ /dev/null sleep .5 for i in `jot 30`; do truss /tmp/ttruss 10 > /dev/null 2>&1 & sleep 11 if ps -l | grep -v grep | grep -q uwrlck; then echo FAIL ps -lH | egrep -v "grep|truss.sh" | grep truss while pkill -9 swap; do : done exit 1 fi wait done while pkill -9 swap; do : done sleep 2 if pgrep -q ttruss; then echo FAIL ps -lH | grep -v grep | grep ttruss exit 1 fi rm -rf /tmp/ttruss exit EOF #include #include #include #include #include #include #include #include #include #define THREADS 16 static void * t1(void *data __unused) { return (NULL); } int main(int argc, char *argv[]) { pthread_t tid[THREADS]; time_t start; int i, rc, runtime; if (argc != 2) errx(1, "Usage: %s ", argv[0]); runtime = atoi(argv[1]); start = time(NULL); while ((time(NULL) - start) < runtime) { for (i = 0; i < THREADS; i++) { - if ((rc = pthread_create(&tid[i], NULL, t1, NULL)) == - -1) + if ((rc = pthread_create(&tid[i], NULL, t1, NULL)) != + 0) errc(1, rc, "pthread_create"); } for (i = 0; i < THREADS; i++) { - if ((rc = pthread_join(tid[i], NULL)) == -1) + if ((rc = pthread_join(tid[i], NULL)) != 0) errc(1, rc, "pthread_join"); } } return (0); } Index: user/pho/stress2/testcases/thr1/thr1.c =================================================================== --- user/pho/stress2/testcases/thr1/thr1.c (revision 291420) +++ user/pho/stress2/testcases/thr1/thr1.c (revision 291421) @@ -1,78 +1,78 @@ /*- * Copyright (c) 2008 Peter Holm * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include "stress.h" #define NTHREADS 256 int setup(int nb __unused) { return (0); } void cleanup(void) { } void * thr_routine(void *arg __unused) { (void) getpid(); return (0); } int test(void) { pthread_t threads[NTHREADS]; int i; int r; for (i = 0; i < NTHREADS; i++) if ((r = pthread_create(&threads[i], NULL, thr_routine, 0)) != 0) err(1, "pthread_create(): %s\n", strerror(r)); for (i = 0; i < NTHREADS; i++) - if (pthread_join(threads[i], NULL) != 0) - err(1, "pthread_join(%d)", i); + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); return (0); } Index: user/pho/stress2/testcases/thr2/thr2.c =================================================================== --- user/pho/stress2/testcases/thr2/thr2.c (revision 291420) +++ user/pho/stress2/testcases/thr2/thr2.c (revision 291421) @@ -1,96 +1,96 @@ /*- * Copyright (c) 2008 Peter Holm * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include "stress.h" #define NTHREADS 256 volatile int done = 0; int setup(int nb __unused) { return (0); } void cleanup(void) { } void * thr1(void *arg __unused) { return (0); } void * thr2(void *arg __unused) { while (done == 0) pthread_yield(); return (0); } int test(void) { pthread_t threads[NTHREADS]; int i; int r; for (i = 0; i < NTHREADS; i++) if ((r = pthread_create(&threads[i], NULL, thr1, 0)) != 0) err(1, "pthread_create(): %s\n", strerror(r)); for (i = 0; i < NTHREADS; i++) if (pthread_join(threads[i], NULL) != 0) err(1, "pthread_join(%d)", i); for (i = 0; i < NTHREADS; i++) if ((r = pthread_create(&threads[i], NULL, thr2, 0)) != 0) err(1, "pthread_create(): %s\n", strerror(r)); done = 1; for (i = 0; i < NTHREADS; i++) - if (pthread_join(threads[i], NULL) != 0) - err(1, "pthread_join(%d)", i); + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); return (0); }