1#!/bin/sh 2 3# 4# Copyright (c) 2015 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# truss(1) of a multithreaded program. 30 31# FAIL 32# 0 90968 90933 0 52 0 6028 0 wait IW+ 1 0:00,00 truss /tmp/ttruss 33# 0 90970 90968 0 52 0 6436 1560 uwrlck IX+ 1 0:00,00 /tmp/ttruss 34# $ procstat -k 90970 35# PID TID COMM TDNAME KSTACK 36# 90970 101244 ttruss - mi_switch sleepq_switch 37# sleepq_catch_signals sleepq_wait_sig _sleep umtxq_sleep 38# do_rw_wrlock __umtx_op_rw_wrlock syscall Xint0x80_syscall 39# $ 40 41# Only seen during testing of a WiP ptrace(2) patch. 42 43. ../default.cfg 44 45dir=/tmp 46odir=`pwd` 47cd $dir 48sed '1,/^EOF/d' < $odir/$0 > $dir/ttruss.c 49mycc -o ttruss -Wall -Wextra -O0 -g ttruss.c -lpthread || exit 1 50rm -f ttruss.c 51 52# VM pressure is not mandatory, but shortens the time to failure. 53daemon sh -c \ 54 "(cd $odir/../testcases/swap; ./swap -t 6m -i 20 -k -l 100)" > \ 55 /dev/null 56sleep .5 57for i in `jot 30`; do 58 truss /tmp/ttruss 10 > /dev/null 2>&1 & 59 sleep 11 60 if ps -lx | grep -v grep | grep -q uwrlck; then 61 echo FAIL 62 ps -lH | egrep -v "grep|truss.sh" | grep truss 63 while pkill -9 swap; do 64 : 65 done 66 exit 1 67 fi 68 wait 69done 70while pkill -9 swap; do 71 : 72done 73sleep 2 74if pgrep -q ttruss; then 75 echo FAIL 76 ps -lxH | grep -v grep | grep ttruss 77 s=1 78fi 79 80[ -f /tmp/truss.core ] && { ls -l /tmp/truss.core; s=1; } 81rm -rf /tmp/ttruss /tmp/ttruss.core 82exit $s 83 84EOF 85#include <sys/param.h> 86 87#include <err.h> 88#include <errno.h> 89#include <fcntl.h> 90#include <pthread.h> 91#include <stdio.h> 92#include <stdlib.h> 93#include <time.h> 94#include <unistd.h> 95 96#define THREADS 16 97 98static void * 99t1(void *data __unused) 100{ 101 return (NULL); 102} 103 104int 105main(int argc, char *argv[]) 106{ 107 pthread_t tid[THREADS]; 108 time_t start; 109 int i, rc, runtime; 110 111 if (argc != 2) 112 errx(1, "Usage: %s <runtime>", argv[0]); 113 runtime = atoi(argv[1]); 114 start = time(NULL); 115 while ((time(NULL) - start) < runtime) { 116 for (i = 0; i < THREADS; i++) { 117 if ((rc = pthread_create(&tid[i], NULL, t1, NULL)) != 118 0) 119 errc(1, rc, "pthread_create"); 120 } 121 122 for (i = 0; i < THREADS; i++) { 123 if ((rc = pthread_join(tid[i], NULL)) != 0) 124 errc(1, rc, "pthread_join"); 125 } 126 } 127 128 return (0); 129} 130