Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/8036666/GetObjectLockCount.java
41153 views
/*1* Copyright (c) 2014 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*/2223import java.io.BufferedReader;24import java.io.IOException;25import java.io.InputStream;26import java.io.InputStreamReader;27import java.util.Iterator;28import java.util.List;29import java.util.Map;3031import com.sun.jdi.AbsentInformationException;32import com.sun.jdi.Bootstrap;33import com.sun.jdi.LocalVariable;34import com.sun.jdi.Location;35import com.sun.jdi.ObjectReference;36import com.sun.jdi.ReferenceType;37import com.sun.jdi.StackFrame;38import com.sun.jdi.ThreadReference;39import com.sun.jdi.Value;40import com.sun.jdi.VirtualMachine;41import com.sun.jdi.connect.Connector;42import com.sun.jdi.connect.Connector.Argument;43import com.sun.jdi.connect.IllegalConnectorArgumentsException;44import com.sun.jdi.connect.LaunchingConnector;45import com.sun.jdi.connect.VMStartException;46import com.sun.jdi.event.BreakpointEvent;47import com.sun.jdi.event.ClassPrepareEvent;48import com.sun.jdi.event.Event;49import com.sun.jdi.event.EventQueue;50import com.sun.jdi.event.EventSet;51import com.sun.jdi.event.VMDeathEvent;52import com.sun.jdi.event.VMDisconnectEvent;53import com.sun.jdi.event.VMStartEvent;54import com.sun.jdi.request.BreakpointRequest;55import com.sun.jdi.request.ClassPrepareRequest;56import com.sun.jdi.request.EventRequestManager;575859/*60* @test GetObjectLockCount.java61* @bug 803666662* @summary verify jvm returns correct lock recursion count63* @requires vm.jvmti64* @run compile -g RecursiveObjectLock.java65* @run main/othervm GetObjectLockCount66* @author [email protected]67*/6869public class GetObjectLockCount {7071public static final String CLASS_NAME = "RecursiveObjectLock";72public static final String METHOD_NAME = "breakpoint1";73public static final String ARGUMENTS = "";747576/**77* Find a com.sun.jdi.CommandLineLaunch connector78*/79static LaunchingConnector findLaunchingConnector() {80List <Connector> connectors = Bootstrap.virtualMachineManager().allConnectors();81Iterator <Connector> iter = connectors.iterator();82while (iter.hasNext()) {83Connector connector = iter.next();84if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {85return (LaunchingConnector)connector;86}87}88throw new Error("No launching connector");89}9091static VirtualMachine launchTarget(String mainArgs) {92LaunchingConnector connector = findLaunchingConnector();93Map<String, Argument> arguments = connectorArguments(connector, mainArgs);94try {95return (VirtualMachine) connector.launch(arguments);96} catch (IOException exc) {97throw new Error("Unable to launch target VM: " + exc);98} catch (IllegalConnectorArgumentsException exc) {99throw new Error("Internal error: " + exc);100} catch (VMStartException exc) {101throw new Error("Target VM failed to initialize: " +102exc.getMessage());103}104}105/**106* Return the launching connector's arguments.107*/108static Map <String,Connector.Argument> connectorArguments(LaunchingConnector connector, String mainArgs) {109Map<String,Connector.Argument> arguments = connector.defaultArguments();110111Connector.Argument mainArg = (Connector.Argument)arguments.get("main");112if (mainArg == null) {113throw new Error("Bad launching connector");114}115mainArg.setValue(mainArgs);116117Connector.Argument optionsArg = (Connector.Argument)arguments.get("options");118if (optionsArg == null) {119throw new Error("Bad launching connector");120}121optionsArg.setValue(ARGUMENTS);122return arguments;123}124125private static void addClassWatch(VirtualMachine vm) {126EventRequestManager erm = vm.eventRequestManager();127ClassPrepareRequest classPrepareRequest = erm128.createClassPrepareRequest();129classPrepareRequest.addClassFilter(CLASS_NAME);130classPrepareRequest.setEnabled(true);131}132133private static void addBreakpoint(VirtualMachine vm, ReferenceType refType) {134Location breakpointLocation = null;135List<Location> locs;136try {137locs = refType.allLineLocations();138for (Location loc: locs) {139if (loc.method().name().equals(METHOD_NAME)) {140breakpointLocation = loc;141break;142}143}144} catch (AbsentInformationException e) {145// TODO Auto-generated catch block146e.printStackTrace();147}148if (breakpointLocation != null) {149EventRequestManager evtReqMgr = vm.eventRequestManager();150BreakpointRequest bReq = evtReqMgr.createBreakpointRequest(breakpointLocation);151bReq.setSuspendPolicy(BreakpointRequest.SUSPEND_ALL);152bReq.enable();153}154}155156/**157* @param args158* @throws InterruptedException159*/160public static void main(String[] args) throws InterruptedException {161162VirtualMachine vm = launchTarget(CLASS_NAME);163164// process events165EventQueue eventQueue = vm.eventQueue();166// resume the vm167boolean launched = false;168169while (!launched) {170EventSet eventSet = eventQueue.remove();171for (Event event : eventSet) {172if (event instanceof VMStartEvent) {173System.out.println("Vm launched");174// set watch field on already loaded classes175List<ReferenceType> referenceTypes = vm.classesByName(CLASS_NAME);176for (ReferenceType refType : referenceTypes) {177System.out.println("Found Class");178addBreakpoint(vm, refType);179}180181// watch for loaded classes182addClassWatch(vm);183vm.resume();184launched = true;185}186}187}188189Process process = vm.process();190191// Copy target's output and error to our output and error.192Thread outThread = new StreamRedirectThread("out reader", process.getInputStream());193Thread errThread = new StreamRedirectThread("error reader", process.getErrorStream());194195int recursionCount = -1;196197errThread.start();198outThread.start();199boolean connected = true;200while (connected) {201EventSet eventSet = eventQueue.remove();202for (Event event : eventSet) {203if (event instanceof VMDeathEvent || event instanceof VMDisconnectEvent) {204// exit205connected = false;206}207else if (event instanceof ClassPrepareEvent) {208// watch field on loaded class209System.out.println("ClassPrepareEvent");210ClassPrepareEvent classPrepEvent = (ClassPrepareEvent) event;211ReferenceType refType = classPrepEvent.referenceType();212addBreakpoint(vm, refType);213} else if (event instanceof BreakpointEvent) {214recursionCount = getLockRecursions(vm);215System.out.println("resume...");216}217}218eventSet.resume();219}220// Shutdown begins when event thread terminates221try {222errThread.join(); // Make sure output is forwarded223outThread.join();224} catch (InterruptedException e) {225// we don't interrupt226e.printStackTrace();227}228if (recursionCount != 3) {229throw new AssertionError("recursions: expected 3, but was " + recursionCount);230}231}232233public static int getLockRecursions(VirtualMachine vm) {234List <ThreadReference> threads = vm.allThreads();235for (ThreadReference thread : threads) {236if (thread.name().equals("main")) {237238System.out.println("Found main thread.");239try{240StackFrame frame = thread.frame(3);241return frame.thisObject().entryCount();242} catch (Exception e) {243e.printStackTrace();244}245}246System.out.println("Main thread not found!");247}248return -1;249}250}251252class StreamRedirectThread extends Thread {253254private final BufferedReader in;255256private static final int BUFFER_SIZE = 2048;257258/**259* Set up for copy.260* @param name Name of the thread261* @param in Stream to copy from262*/263StreamRedirectThread(String name, InputStream in) {264super(name);265this.in = new BufferedReader(new InputStreamReader(in));266}267268/**269* Copy.270*/271public void run() {272try {273String line;274while ((line = in.readLine ()) != null) {275System.out.println("testvm: " + line);276}277System.out.flush();278} catch(IOException exc) {279System.err.println("Child I/O Transfer - " + exc);280exc.printStackTrace();281}282}283}284285286