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 "WARNING: 'jmap $jmap_option' is not supported on this platform" |
|
87 echo "WARNING: so this test cannot work reliably. Aborting!" |
|
88 exit 0 |
|
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 |
|