1 #!/bin/sh 2 3 # 4 # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 5 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 # 7 # This code is free software; you can redistribute it and/or modify it 8 # under the terms of the GNU General Public License version 2 only, as 9 # published by the Free Software Foundation. 10 # 11 # This code is distributed in the hope that it will be useful, but WITHOUT 12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 # version 2 for more details (a copy is included in the LICENSE file that 15 # accompanied this code). 16 # 17 # You should have received a copy of the GNU General Public License version 18 # 2 along with this work; if not, write to the Free Software Foundation, 19 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 # 21 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 # or visit www.oracle.com if you need additional information or have any 23 # questions. 24 # 25 26 # @test 27 # @bug 6942989 28 # @summary Check for WeakReference leak in Logger objects 29 # @author Daniel D. Daugherty 30 # 31 # @library ../../../sun/tools/common 32 # @build SimpleApplication ShutdownSimpleApplication 33 # @build LoggerWeakRefLeak 34 # @run shell/timeout=240 LoggerWeakRefLeak.sh 35 36 # The timeout is: 2 minutes for infrastructure and 2 minutes for the test 37 # 38 39 . ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh 40 . ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh 41 42 43 TEST_NAME="LoggerWeakRefLeak" 44 TARGET_CLASS="java\.lang\.ref\.WeakReference" 45 46 47 # MAIN begins here 48 # 49 50 seconds= 51 if [ "$#" -gt 0 ]; then 52 seconds="$1" 53 fi 54 55 # see if this version of jmap supports the '-histo:live' option 56 jmap_option="-histo:live" 57 set +e 58 "${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1 59 status="$?" 60 set -e 61 if [ "$status" != 0 ]; then 62 # usage message doesn't show ':live' option 63 64 if $isWindows; then 65 # If SA isn't present, then jmap gives a different usage message 66 # that doesn't show the ':live' option. However, that's a bug that 67 # is covered by 6971851 so we try using the option just to be sure. 68 # For some reason, this problem has only been seen on OpenJDK6 on 69 # Windows. Not sure why. 70 set +e 71 # Note: Don't copy this code to try probing process 0 on Linux; it 72 # will kill the process group in strange ways. 73 "${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1 74 status="$?" 75 set -e 76 if [ "$status" = 0 ]; then 77 # Usage message generated so flag the problem. 78 status=1 79 else 80 # No usage message so clear the flag. 81 status=0 82 fi 83 fi 84 85 if [ "$status" != 0 ]; then 86 echo "ERROR: 'jmap $jmap_option' is not supported so this test" 87 echo "ERROR: cannot work reliably. Aborting!" 88 exit 2 89 fi 90 fi 91 92 # Start application and use TEST_NAME.port for coordination 93 startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds 94 95 finished_early=false 96 97 decreasing_cnt=0 98 increasing_cnt=0 99 loop_cnt=0 100 prev_instance_cnt=0 101 102 MAX_JMAP_TRY_CNT=10 103 jmap_retry_cnt=0 104 loop_cnt_on_retry=0 105 106 while true; do 107 # see if the target process has finished its run and bail if it has 108 set +e 109 grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1 110 status="$?" 111 set -e 112 if [ "$status" = 0 ]; then 113 break 114 fi 115 116 # Output format for 'jmap -histo' in JDK1.5.0: 117 # 118 # <#bytes> <#instances> <class_name> 119 # 120 # Output format for 'jmap -histo:live': 121 # 122 # <num>: <#instances> <#bytes> <class_name> 123 # 124 set +e 125 "${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1 126 status="$?" 127 set -e 128 129 if [ "$status" != 0 ]; then 130 echo "INFO: jmap exited with exit code = $status" 131 132 # There are intermittent jmap failures; see 6498448. 133 # 134 # So far the following have been observed in a jmap call 135 # that was not in a race with target process termination: 136 # 137 # (Solaris specific, 2nd sample) 138 # <pid>: Unable to open door: target process not responding or HotSpot VM not loaded 139 # The -F option can be used when the target process is not responding 140 # 141 # (on Solaris so far) 142 # java.io.IOException 143 # 144 # (on Solaris so far, 1st sample) 145 # <pid>: Permission denied 146 # 147 sed 's/^/INFO: /' "$TEST_NAME.jmap" 148 149 if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then 150 # loop count hasn't changed 151 jmap_retry_cnt=`expr $jmap_retry_cnt + 1` 152 else 153 # loop count has changed so remember it 154 jmap_retry_cnt=1 155 loop_cnt_on_retry="$loop_cnt" 156 fi 157 158 # This is '-ge' because we have the original attempt plus 159 # MAX_JMAP_TRY_CNT - 1 retries. 160 if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then 161 echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \ 162 "without making any progress." 163 echo "FAIL: jmap is unable to take any samples." >&2 164 killApplication 165 exit 2 166 fi 167 168 # short delay and try again 169 # Note: sleep 1 didn't help with "<pid>: Permission denied" 170 sleep 2 171 echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)." 172 continue 173 fi 174 175 set +e 176 instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \ 177 "$TEST_NAME.jmap" \ 178 | sed ' 179 # strip leading whitespace; does nothing in JDK1.5.0 180 s/^'"${PATTERN_WS}${PATTERN_WS}"'*// 181 # strip <#bytes> in JDK1.5.0; does nothing otherwise 182 s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*// 183 # strip <num>: field; does nothing in JDK1.5.0 184 s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*// 185 # strip <class_name> field 186 s/'"${PATTERN_WS}"'.*// 187 '` 188 set -e 189 if [ -z "$instance_cnt" ]; then 190 echo "INFO: instance count is unexpectedly empty" 191 if [ "$loop_cnt" = 0 ]; then 192 echo "INFO: on the first iteration so no sample was found." 193 echo "INFO: There is likely a problem with the sed filter." 194 echo "INFO: start of jmap output:" 195 cat "$TEST_NAME.jmap" 196 echo "INFO: end of jmap output." 197 echo "FAIL: cannot find the instance count value." >&2 198 killApplication 199 exit 2 200 fi 201 else 202 echo "INFO: instance_cnt = $instance_cnt" 203 204 if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then 205 increasing_cnt=`expr $increasing_cnt + 1` 206 else 207 # actually decreasing or the same 208 decreasing_cnt=`expr $decreasing_cnt + 1` 209 210 # For these particular WeakReference leaks, the count was 211 # always observed to be increasing so if we get a decreasing 212 # or the same count, then the leaks are fixed in the bits 213 # being tested. 214 echo "INFO: finishing early due to non-increasing instance count." 215 finished_early=true 216 killApplication 217 break 218 fi 219 prev_instance_cnt="$instance_cnt" 220 fi 221 222 # delay between samples 223 sleep 5 224 225 loop_cnt=`expr $loop_cnt + 1` 226 done 227 228 if [ $finished_early = false ]; then 229 stopApplication "$TEST_NAME.port" 230 waitForApplication 231 fi 232 233 echo "INFO: $TEST_NAME has finished running." 234 echo "INFO: increasing_cnt = $increasing_cnt" 235 echo "INFO: decreasing_cnt = $decreasing_cnt" 236 if [ "$jmap_retry_cnt" -gt 0 ]; then 237 echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)" 238 fi 239 240 if [ "$loop_cnt" = 0 ]; then 241 echo "FAIL: jmap is unable to take any samples." >&2 242 exit 2 243 fi 244 245 echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects" 246 if [ "$decreasing_cnt" = 0 ]; then 247 echo "INFO: is always increasing." 248 echo "FAIL: This indicates that there is a memory leak." >&2 249 exit 2 250 fi 251 252 echo "INFO: is not always increasing." 253 echo "PASS: This indicates that there is not a memory leak." 254 exit 0