Path: blob/master/test/hotspot/jtreg/runtime/7158988/FieldMonitor.java
40942 views
/*1* Copyright (c) 2012 SAP SE. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test FieldMonitor.java25* @bug 715898826* @requires vm.jvmti27* @summary verify jvm does not crash while debugging28* @run compile TestPostFieldModification.java29* @run main/othervm FieldMonitor30* @author [email protected]31*/32import java.io.BufferedReader;33import java.io.IOException;34import java.io.InputStream;35import java.io.InputStreamReader;36import java.util.Iterator;37import java.util.List;38import java.util.Map;3940import com.sun.jdi.Bootstrap;41import com.sun.jdi.Field;42import com.sun.jdi.ReferenceType;43import com.sun.jdi.VirtualMachine;44import com.sun.jdi.connect.Connector;45import com.sun.jdi.connect.IllegalConnectorArgumentsException;46import com.sun.jdi.connect.LaunchingConnector;47import com.sun.jdi.connect.VMStartException;48import com.sun.jdi.event.ClassPrepareEvent;49import com.sun.jdi.event.Event;50import com.sun.jdi.event.EventQueue;51import com.sun.jdi.event.EventSet;52import com.sun.jdi.event.ModificationWatchpointEvent;53import com.sun.jdi.event.VMDeathEvent;54import com.sun.jdi.event.VMStartEvent;55import com.sun.jdi.event.VMDisconnectEvent;56import com.sun.jdi.request.ClassPrepareRequest;57import com.sun.jdi.request.EventRequest;58import com.sun.jdi.request.EventRequestManager;59import com.sun.jdi.request.ModificationWatchpointRequest;6061public class FieldMonitor {6263public static final String CLASS_NAME = "TestPostFieldModification";64public static final String FIELD_NAME = "value";65public static final String ARGUMENTS = "-Xshare:off -Xlog:gc";6667public static void main(String[] args)68throws IOException, InterruptedException {6970//VirtualMachine vm = launchTarget(sb.toString());71VirtualMachine vm = launchTarget(CLASS_NAME);7273System.out.println("Vm launched");7475// process events76EventQueue eventQueue = vm.eventQueue();77// resume the vm7879Process process = vm.process();808182// Copy target's output and error to our output and error.83Thread outThread = new StreamRedirectThread("out reader", process.getInputStream());84Thread errThread = new StreamRedirectThread("error reader", process.getErrorStream());8586errThread.start();87outThread.start();8889boolean connected = true;90int watched = 0;91while (connected) {92try {93EventSet eventSet = eventQueue.remove();94for (Event event : eventSet) {95System.out.println("FieldMonitor-main receives: "+event);96if (event instanceof VMStartEvent) {97addClassWatch(vm);98} else if (event instanceof VMDeathEvent99|| event instanceof VMDisconnectEvent) {100// exit101connected = false;102} else if (event instanceof ClassPrepareEvent) {103// watch field on loaded class104System.out.println("ClassPrepareEvent");105ClassPrepareEvent classPrepEvent = (ClassPrepareEvent) event;106ReferenceType refType = classPrepEvent107.referenceType();108addFieldWatch(vm, refType);109} else if (event instanceof ModificationWatchpointEvent) {110watched++;111System.out.println("sleep for 500 ms");112Thread.sleep(500);113114ModificationWatchpointEvent modEvent = (ModificationWatchpointEvent) event;115System.out.println("old="116+ modEvent.valueCurrent());117System.out.println("new=" + modEvent.valueToBe());118}119}120System.out.println("resume...");121eventSet.resume();122} catch (com.sun.jdi.VMDisconnectedException exc) {123// Guess this means it's not connected anymore,124// sometimes this happens and everything else hangs, just return.125return;126}127}128// Shutdown begins when event thread terminates129try {130errThread.join(); // Make sure output is forwarded131outThread.join();132} catch (InterruptedException exc) {133// we don't interrupt134}135136if (watched != 11) { // init + 10 modifications in TestPostFieldModification class137throw new Error("Expected to receive 11 times ModificationWatchpointEvent, but got "+watched);138}139}140141/**142* Find a com.sun.jdi.CommandLineLaunch connector143*/144static LaunchingConnector findLaunchingConnector() {145List <Connector> connectors = Bootstrap.virtualMachineManager().allConnectors();146Iterator <Connector> iter = connectors.iterator();147while (iter.hasNext()) {148Connector connector = iter.next();149if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {150return (LaunchingConnector)connector;151}152}153throw new Error("No launching connector");154}155/**156* Return the launching connector's arguments.157*/158static Map <String,Connector.Argument> connectorArguments(LaunchingConnector connector, String mainArgs) {159Map<String,Connector.Argument> arguments = connector.defaultArguments();160for (String key : arguments.keySet()) {161System.out.println(key);162}163164Connector.Argument mainArg = (Connector.Argument)arguments.get("main");165if (mainArg == null) {166throw new Error("Bad launching connector");167}168mainArg.setValue(mainArgs);169170Connector.Argument optionsArg = (Connector.Argument)arguments.get("options");171if (optionsArg == null) {172throw new Error("Bad launching connector");173}174optionsArg.setValue(ARGUMENTS);175return arguments;176}177178static VirtualMachine launchTarget(String mainArgs) {179LaunchingConnector connector = findLaunchingConnector();180Map arguments = connectorArguments(connector, mainArgs);181try {182return (VirtualMachine) connector.launch(arguments);183} catch (IOException exc) {184throw new Error("Unable to launch target VM: " + exc);185} catch (IllegalConnectorArgumentsException exc) {186throw new Error("Internal error: " + exc);187} catch (VMStartException exc) {188throw new Error("Target VM failed to initialize: " +189exc.getMessage());190}191}192193194private static void addClassWatch(VirtualMachine vm) {195EventRequestManager erm = vm.eventRequestManager();196ClassPrepareRequest classPrepareRequest = erm197.createClassPrepareRequest();198classPrepareRequest.addClassFilter(CLASS_NAME);199classPrepareRequest.setEnabled(true);200}201202203private static void addFieldWatch(VirtualMachine vm,204ReferenceType refType) {205EventRequestManager erm = vm.eventRequestManager();206Field field = refType.fieldByName(FIELD_NAME);207ModificationWatchpointRequest modificationWatchpointRequest = erm208.createModificationWatchpointRequest(field);209modificationWatchpointRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);210modificationWatchpointRequest.setEnabled(true);211}212}213214class StreamRedirectThread extends Thread {215216private final BufferedReader in;217218private static final int BUFFER_SIZE = 2048;219220/**221* Set up for copy.222* @param name Name of the thread223* @param in Stream to copy from224* @param out Stream to copy to225*/226StreamRedirectThread(String name, InputStream in) {227super(name);228this.in = new BufferedReader(new InputStreamReader(in));229}230231/**232* Copy.233*/234public void run() {235try {236String line;237while ((line = in.readLine ()) != null) {238System.out.println ("testvm: " + line);239}240System.out.flush();241} catch(IOException exc) {242System.err.println("Child I/O Transfer - " + exc);243}244}245}246247248