Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdi/HiddenClass/events/EventHandler.java
41161 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. 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*/2223package nsk.jdi.HiddenClass.events;2425import com.sun.jdi.ClassType;26import com.sun.jdi.Field;27import com.sun.jdi.Method;28import com.sun.jdi.ReferenceType;29import com.sun.jdi.ThreadReference;3031import com.sun.jdi.event.Event;32import com.sun.jdi.event.EventIterator;33import com.sun.jdi.event.EventSet;34import com.sun.jdi.event.BreakpointEvent;35import com.sun.jdi.event.ClassPrepareEvent;36import com.sun.jdi.event.ClassUnloadEvent;37import com.sun.jdi.event.ModificationWatchpointEvent;38import com.sun.jdi.request.EventRequest;3940import jdk.test.lib.Asserts;41import nsk.jdi.HiddenClass.events.DebuggerBase;4243import nsk.share.Log;4445/* This is a special thread to handle hidden class related events.46* The thread is looping on accepting events until all the expected47* event types are received. */48public class EventHandler extends Thread {49private static final int TIMEOUT_DELTA = 1000; // milliseconds50private final DebuggerBase debuggerBase;51private final Log log;5253private volatile boolean testFailed = false;54private boolean breakpointEventRecieived = false;55private boolean classPrepareEventRecieived = false;56private boolean classUnloadEventRecieived = false;57private boolean modificationWatchpointEventRecieived = false;5859// Hidden class ReferenceType which is saved for debugger.60private ReferenceType hcRefType = null;6162// This method is called by the debugger main thread.63static EventHandler createAndStart(DebuggerBase debuggerBase) {64// start EventHandler thread65EventHandler handler = new EventHandler(debuggerBase);66handler.start();67return handler;68}6970// Constructor71private EventHandler(DebuggerBase debuggerBase) {72this.debuggerBase = debuggerBase;73this.log = debuggerBase.log;74log.display("\n# EventHandler is started");75}7677// This method is called by the debugger main thread.78void waitForCompleteness() {79log.display("\n# Waiting for EventHandler to complete");80// wait for all expected events received or timeout exceeds81try {82super.join();83if (isAlive()) {84log.complain("FAILURE: Timeout for waiting event was exceeded");85interrupt();86testFailed = true;87} else {88log.display("# EventHandler completed");89}90} catch (InterruptedException ie) {91log.complain("FAIL: InterruptedException caught while waiting for eventHandler's death");92testFailed = true;93}94}9596// This method is called by the debugger main thread to wait and get97// the hidden class reference type from its ClassPrepare event.98// The readyCmdSync with the debuggeee is not enough because a99// ClassPrepare event is delivered over JDWP protocol with a delay.100// A wait/notify sync is to ensure the debugger gets non-null value.101synchronized ReferenceType waitAndGetHCRefType() throws InterruptedException {102while (hcRefType == null) {103wait();104}105return hcRefType;106}107108// This method is called by the debugger main thread.109boolean failedStatus() { return testFailed; }110111// Save hidden class ReferenceType when its ClassPrepare event is received.112private synchronized void setHCRefType(ReferenceType type) {113hcRefType = type;114notifyAll();115}116117private EventSet getNextEventSet() throws InterruptedException {118EventSet eventSet = debuggerBase.vm().eventQueue().remove(TIMEOUT_DELTA);119return eventSet;120}121122// Breakpoint event handler.123private void checkBreakpointEvent(BreakpointEvent event) {124Method method = event.location().method();125ClassType type = (ClassType)method.declaringType();126127// got expected event in a hidden class method128log.display("\nBreakpointEvent: " + event.toString());129log.display("BreakpointEvent: " + type.name() + "::" + method.name());130breakpointEventRecieived = true;131132// find another method in the same hidden class133ThreadReference thread = event.thread();134Method methodToInvoke = debuggerBase.findMethod(type, "getHCField");135136// invoke hidden class static method getNCField in debuggee VM137testFailed |= debuggerBase.invokeStaticMethod(thread, methodToInvoke);138}139140// ClassPrepare event handler.141private void checkClassPrepareEvent(ClassPrepareEvent event) {142ReferenceType type = event.referenceType();143String name = type.name();144String sign = type.signature();145146// set hidden class ReferenceType object for debugger147setHCRefType(type);148149log.display("\nClassPrepareEvent: " + event.toString());150log.display("ClassPrepareEvent class name: " + name);151log.display("ClassPrepareEvent class sign: " + sign);152classPrepareEventRecieived = true;153Asserts.assertTrue(name.indexOf("HiddenClass") > 0 && name.indexOf("/0x") > 0,154"FAIL: unexpected class in ClassPrepareEvent");155}156157// ClassUnload event handler.158private void checkClassUnloadEvent(ClassUnloadEvent event) {159EventRequest request = event.request();160String name = event.className();161162log.display("\nClassUnloadEvent class name: " + name);163log.display("ClassUnloadEvent class sign: " + event.classSignature());164classUnloadEventRecieived = true;165Asserts.assertTrue(name.indexOf("HiddenClass") > 0 && name.indexOf("/0x") > 0,166"FAIL: unexpected class in ClassUnloadEvent");167}168169// ModificationWatchpoint event handler.170private void checkModificationWatchpointEvent(ModificationWatchpointEvent event) {171EventRequest request = event.request();172Field field = event.field();173ReferenceType type = field.declaringType();174log.display("\nModificationWatchpointEvent: " + event.toString());175log.display("ModificationWatchpointEvent: field: " + type.name() + "::" + field.name());176log.display("ModificationWatchpointEvent: value: " + event.valueToBe().toString());177modificationWatchpointEventRecieived = true;178}179180private void processEventSet(EventSet eventSet) throws InterruptedException {181// handle each event from the event set182EventIterator eventIterator = eventSet.eventIterator();183while (eventIterator.hasNext()) {184Event event = eventIterator.nextEvent();185186if (!breakpointEventRecieived &&187event instanceof BreakpointEvent) {188checkBreakpointEvent((BreakpointEvent)event);189}190if (!classPrepareEventRecieived &&191event instanceof ClassPrepareEvent) {192checkClassPrepareEvent((ClassPrepareEvent)event);193}194if (!classUnloadEventRecieived &&195event instanceof ClassUnloadEvent) {196checkClassUnloadEvent((ClassUnloadEvent)event);197}198if (!modificationWatchpointEventRecieived &&199event instanceof ModificationWatchpointEvent) {200checkModificationWatchpointEvent((ModificationWatchpointEvent)event);201}202// ignore all other events203}204}205206public void run() {207log.display("\nEventHandler started");208try {209// Handle events until all expected events are received.210while (!breakpointEventRecieived ||211!classPrepareEventRecieived ||212!classUnloadEventRecieived ||213!modificationWatchpointEventRecieived214) {215EventSet eventSet = getNextEventSet();216if (eventSet == null) {217continue;218}219processEventSet(eventSet);220eventSet.resume();221}222} catch (Throwable t) {223log.complain("Throwable in EventHandler: " + t);224testFailed = true;225}226log.display("\nEventHandler finished");227}228} // class EventHandler229230231