comparison test/runtime/7158988/TestPostFieldModification.java @ 6004:0f701f572aed

Merge
author coleenp
date Fri, 13 Apr 2012 08:11:36 -0700
parents 27dab8a7c762
children
comparison
equal deleted inserted replaced
6002:df4cd4aac5c1 6004:0f701f572aed
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 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 20 * or visit www.oracle.com if you need additional information or have any
21 * questions. 21 * questions.
22 */ 22 */
23 23
24 /* 24 public class TestPostFieldModification {
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 25
43 import com.sun.jdi.Bootstrap; 26 public String value; // watch modification of value
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 27
63 public class FieldMonitor { 28 public static void main(String[] args){
64 29
65 public static final String CLASS_NAME = "TestPostFieldModification"; 30 System.out.println("Start threads");
66 public static final String FIELD_NAME = "value"; 31 // this thread modifies the field 'value'
67 public static final String ARGUMENTS = "-Xshare:off -XX:+PrintGC"; 32 new Thread() {
68 33 TestPostFieldModification test = new TestPostFieldModification();
69 public static void main(String[] args) 34 public void run() {
70 throws IOException, InterruptedException { 35 test.value="test";
71 36 for(int i = 0; i < 10; i++) {
72 StringBuffer sb = new StringBuffer(); 37 test.value += new String("_test");
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 } 38 }
133 } 39 }
134 eventSet.resume(); 40 }.start();
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 41
145 /** 42 // this thread is used to trigger a gc
146 * Find a com.sun.jdi.CommandLineLaunch connector 43 Thread d = new Thread() {
147 */ 44 public void run() {
148 static LaunchingConnector findLaunchingConnector() { 45 while(true) {
149 List <Connector> connectors = Bootstrap.virtualMachineManager().allConnectors(); 46 try {
150 Iterator <Connector> iter = connectors.iterator(); 47 Thread.sleep(100);
151 while (iter.hasNext()) { 48 } catch (InterruptedException e) {
152 Connector connector = iter.next(); 49
153 if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) { 50 }
154 return (LaunchingConnector)connector; 51 System.gc();
52 }
155 } 53 }
156 } 54 };
157 throw new Error("No launching connector"); 55 d.setDaemon(true);
158 } 56 d.start();
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 } 57 }
216 } 58 }
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 }