Mercurial > hg > graal-jvmci-8
comparison test/runtime/7158988/FieldMonitor.java @ 5995:19e197e2a1af
7158988: jvm crashes while debugging on x86_32 and x86_64
Summary: Object pointer is pushed more than once on stack, where GC doesn't expect it.
Reviewed-by: coleenp, kvn
Contributed-by: axel.siebenborn@sap.com
author | coleenp |
---|---|
date | Thu, 05 Apr 2012 12:17:52 -0400 |
parents | |
children | a7f9a1195d86 |
comparison
equal
deleted
inserted
replaced
5983:749b1464aa81 | 5995:19e197e2a1af |
---|---|
1 /* | |
2 * Copyright 2012 SAP AG. All Rights Reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 | |
24 /* | |
25 * @test FieldMonitor.java | |
26 * @bug 7158988 | |
27 * @summary verify jvm does not crash while debugging | |
28 * @run shell TestFieldMonitor.sh | |
29 * @author axel.siebenborn@sap.com | |
30 */ | |
31 import java.io.BufferedReader; | |
32 import java.io.IOException; | |
33 import java.io.InputStream; | |
34 import java.io.InputStreamReader; | |
35 import java.io.OutputStream; | |
36 import java.io.OutputStreamWriter; | |
37 import java.io.Reader; | |
38 import java.io.Writer; | |
39 import java.util.Iterator; | |
40 import java.util.List; | |
41 import java.util.Map; | |
42 | |
43 import com.sun.jdi.Bootstrap; | |
44 import com.sun.jdi.Field; | |
45 import com.sun.jdi.ReferenceType; | |
46 import com.sun.jdi.VirtualMachine; | |
47 import com.sun.jdi.connect.Connector; | |
48 import com.sun.jdi.connect.IllegalConnectorArgumentsException; | |
49 import com.sun.jdi.connect.LaunchingConnector; | |
50 import com.sun.jdi.connect.VMStartException; | |
51 import com.sun.jdi.event.ClassPrepareEvent; | |
52 import com.sun.jdi.event.Event; | |
53 import com.sun.jdi.event.EventQueue; | |
54 import com.sun.jdi.event.EventSet; | |
55 import com.sun.jdi.event.ModificationWatchpointEvent; | |
56 import com.sun.jdi.event.VMDeathEvent; | |
57 import com.sun.jdi.event.VMDisconnectEvent; | |
58 import com.sun.jdi.request.ClassPrepareRequest; | |
59 import com.sun.jdi.request.EventRequest; | |
60 import com.sun.jdi.request.EventRequestManager; | |
61 import com.sun.jdi.request.ModificationWatchpointRequest; | |
62 | |
63 public class FieldMonitor { | |
64 | |
65 public static final String CLASS_NAME = "TestPostFieldModification"; | |
66 public static final String FIELD_NAME = "value"; | |
67 public static final String ARGUMENTS = "-Xshare:off -XX:+PrintGC"; | |
68 | |
69 public static void main(String[] args) | |
70 throws IOException, InterruptedException { | |
71 | |
72 StringBuffer sb = new StringBuffer(); | |
73 | |
74 for (int i=0; i < args.length; i++) { | |
75 sb.append(' '); | |
76 sb.append(args[i]); | |
77 } | |
78 //VirtualMachine vm = launchTarget(sb.toString()); | |
79 VirtualMachine vm = launchTarget(CLASS_NAME); | |
80 | |
81 System.out.println("Vm launched"); | |
82 // set watch field on already loaded classes | |
83 List<ReferenceType> referenceTypes = vm | |
84 .classesByName(CLASS_NAME); | |
85 for (ReferenceType refType : referenceTypes) { | |
86 addFieldWatch(vm, refType); | |
87 } | |
88 // watch for loaded classes | |
89 addClassWatch(vm); | |
90 | |
91 // process events | |
92 EventQueue eventQueue = vm.eventQueue(); | |
93 // resume the vm | |
94 | |
95 Process process = vm.process(); | |
96 | |
97 | |
98 // Copy target's output and error to our output and error. | |
99 Thread outThread = new StreamRedirectThread("out reader", process.getInputStream()); | |
100 Thread errThread = new StreamRedirectThread("error reader", process.getErrorStream()); | |
101 | |
102 errThread.start(); | |
103 outThread.start(); | |
104 | |
105 | |
106 vm.resume(); | |
107 boolean connected = true; | |
108 while (connected) { | |
109 EventSet eventSet = eventQueue.remove(); | |
110 for (Event event : eventSet) { | |
111 if (event instanceof VMDeathEvent | |
112 || event instanceof VMDisconnectEvent) { | |
113 // exit | |
114 connected = false; | |
115 } else if (event instanceof ClassPrepareEvent) { | |
116 // watch field on loaded class | |
117 System.out.println("ClassPrepareEvent"); | |
118 ClassPrepareEvent classPrepEvent = (ClassPrepareEvent) event; | |
119 ReferenceType refType = classPrepEvent | |
120 .referenceType(); | |
121 addFieldWatch(vm, refType); | |
122 } else if (event instanceof ModificationWatchpointEvent) { | |
123 System.out.println("sleep for 500 ms"); | |
124 Thread.sleep(500); | |
125 System.out.println("resume..."); | |
126 | |
127 ModificationWatchpointEvent modEvent = (ModificationWatchpointEvent) event; | |
128 System.out.println("old=" | |
129 + modEvent.valueCurrent()); | |
130 System.out.println("new=" + modEvent.valueToBe()); | |
131 System.out.println(); | |
132 } | |
133 } | |
134 eventSet.resume(); | |
135 } | |
136 // Shutdown begins when event thread terminates | |
137 try { | |
138 errThread.join(); // Make sure output is forwarded | |
139 outThread.join(); | |
140 } catch (InterruptedException exc) { | |
141 // we don't interrupt | |
142 } | |
143 } | |
144 | |
145 /** | |
146 * Find a com.sun.jdi.CommandLineLaunch connector | |
147 */ | |
148 static LaunchingConnector findLaunchingConnector() { | |
149 List <Connector> connectors = Bootstrap.virtualMachineManager().allConnectors(); | |
150 Iterator <Connector> iter = connectors.iterator(); | |
151 while (iter.hasNext()) { | |
152 Connector connector = iter.next(); | |
153 if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) { | |
154 return (LaunchingConnector)connector; | |
155 } | |
156 } | |
157 throw new Error("No launching connector"); | |
158 } | |
159 /** | |
160 * Return the launching connector's arguments. | |
161 */ | |
162 static Map <String,Connector.Argument> connectorArguments(LaunchingConnector connector, String mainArgs) { | |
163 Map<String,Connector.Argument> arguments = connector.defaultArguments(); | |
164 for (String key : arguments.keySet()) { | |
165 System.out.println(key); | |
166 } | |
167 | |
168 Connector.Argument mainArg = (Connector.Argument)arguments.get("main"); | |
169 if (mainArg == null) { | |
170 throw new Error("Bad launching connector"); | |
171 } | |
172 mainArg.setValue(mainArgs); | |
173 | |
174 Connector.Argument optionsArg = (Connector.Argument)arguments.get("options"); | |
175 if (optionsArg == null) { | |
176 throw new Error("Bad launching connector"); | |
177 } | |
178 optionsArg.setValue(ARGUMENTS); | |
179 return arguments; | |
180 } | |
181 | |
182 static VirtualMachine launchTarget(String mainArgs) { | |
183 LaunchingConnector connector = findLaunchingConnector(); | |
184 Map arguments = connectorArguments(connector, mainArgs); | |
185 try { | |
186 return (VirtualMachine) connector.launch(arguments); | |
187 } catch (IOException exc) { | |
188 throw new Error("Unable to launch target VM: " + exc); | |
189 } catch (IllegalConnectorArgumentsException exc) { | |
190 throw new Error("Internal error: " + exc); | |
191 } catch (VMStartException exc) { | |
192 throw new Error("Target VM failed to initialize: " + | |
193 exc.getMessage()); | |
194 } | |
195 } | |
196 | |
197 | |
198 private static void addClassWatch(VirtualMachine vm) { | |
199 EventRequestManager erm = vm.eventRequestManager(); | |
200 ClassPrepareRequest classPrepareRequest = erm | |
201 .createClassPrepareRequest(); | |
202 classPrepareRequest.addClassFilter(CLASS_NAME); | |
203 classPrepareRequest.setEnabled(true); | |
204 } | |
205 | |
206 | |
207 private static void addFieldWatch(VirtualMachine vm, | |
208 ReferenceType refType) { | |
209 EventRequestManager erm = vm.eventRequestManager(); | |
210 Field field = refType.fieldByName(FIELD_NAME); | |
211 ModificationWatchpointRequest modificationWatchpointRequest = erm | |
212 .createModificationWatchpointRequest(field); | |
213 modificationWatchpointRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); | |
214 modificationWatchpointRequest.setEnabled(true); | |
215 } | |
216 } | |
217 | |
218 class StreamRedirectThread extends Thread { | |
219 | |
220 private final BufferedReader in; | |
221 | |
222 private static final int BUFFER_SIZE = 2048; | |
223 | |
224 /** | |
225 * Set up for copy. | |
226 * @param name Name of the thread | |
227 * @param in Stream to copy from | |
228 * @param out Stream to copy to | |
229 */ | |
230 StreamRedirectThread(String name, InputStream in) { | |
231 super(name); | |
232 this.in = new BufferedReader(new InputStreamReader(in)); | |
233 } | |
234 | |
235 /** | |
236 * Copy. | |
237 */ | |
238 public void run() { | |
239 try { | |
240 String line; | |
241 while ((line = in.readLine ()) != null) { | |
242 System.out.println ("testvm: " + line); | |
243 } | |
244 System.out.flush(); | |
245 } catch(IOException exc) { | |
246 System.err.println("Child I/O Transfer - " + exc); | |
247 } | |
248 } | |
249 } |