Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/OwnedMonitorsDebugger.java
41161 views
/*1* Copyright (c) 2006, 2018, 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*/22package nsk.share.jdi;2324import java.io.*;25import java.util.*;26import com.sun.jdi.*;2728import nsk.share.Consts;2930/*31* Class is used as base debugger in tests for ThreadReference.ownedMonitorsAndFrames().32*33* In all this test similar scenario is used:34* - debugger VM force debugge VM to create test thread which acquires different monitors35* - when test thread acquire all monitors debuggee save information about all acquired monitors in special array 'monitorsInfo'36* - debugger read data from 'monitorsInfo' and compare it with data returned by ThreadReference.ownedMonitorsAndFrames()37*/38public class OwnedMonitorsDebugger extends TestDebuggerType2 {3940/*41* debug data about monitor acquired by debuggee test thread,42* intended to compare with data returned by ThreadReference.ownedMonitorsAndFrames43*/44public static class DebugMonitorInfo {45// create DebugMonitorInfo using mirror of instance of nsk.share.locks.LockingThread.DebugMonitorInfo46DebugMonitorInfo(ObjectReference debuggeeMirror) {47monitor = (ObjectReference) debuggeeMirror.getValue(debuggeeMirror.referenceType().fieldByName("monitor"));48stackDepth = ((IntegerValue) debuggeeMirror.getValue(debuggeeMirror.referenceType().fieldByName("stackDepth"))).intValue();49thread = (ThreadReference) debuggeeMirror.getValue(debuggeeMirror.referenceType().fieldByName("thread"));50}5152public DebugMonitorInfo(ObjectReference monitor, int stackDepth, ThreadReference thread) {53this.monitor = monitor;54this.stackDepth = stackDepth;55this.thread = thread;56}5758public ObjectReference monitor;5960public int stackDepth;6162public ThreadReference thread;63}6465public static void main(String argv[]) {66System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);67}6869public static int run(String argv[], PrintStream out) {70return new OwnedMonitorsDebugger().runIt(argv, out);71}7273protected boolean canRunTest() {74if (!vm.canGetMonitorFrameInfo()) {75log.display("TEST CANCELED due to: vm.canGetMonitorFrameInfo() = false");76return false;77} else78return super.canRunTest();79}8081protected String debuggeeClassName() {82return OwnedMonitorsDebuggee.class.getName();83}8485// read debuggee's array 'monitorsInfo' containing information about acquired monitors86protected List<DebugMonitorInfo> getDebugMonitorsInfo() {87List<DebugMonitorInfo> result = new ArrayList<DebugMonitorInfo>();8889ReferenceType referenceType = debuggee.classByName(debuggeeClassNameWithoutArgs());90ArrayReference monitorsInfo = (ArrayReference) referenceType.getValue(referenceType.fieldByName("monitorsInfo"));9192for (int i = 0; i < monitorsInfo.length(); i++)93result.add(new DebugMonitorInfo((ObjectReference) monitorsInfo.getValue(i)));9495return result;96}9798private boolean compare(MonitorInfo actual, DebugMonitorInfo expected) {99boolean success = true;100101if (actual.stackDepth() != expected.stackDepth) {102setSuccess(false);103success = false;104log.complain("Expected and actual monitor(" + actual.monitor() + ") stack depth differs, expected: " + expected.stackDepth + " actual: "105+ actual.stackDepth());106}107108if (!actual.thread().equals(expected.thread)) {109setSuccess(false);110success = false;111log.complain("Expected and actual monitor(" + actual.monitor() + " thread differs, expected: " + expected.thread + " actual: "112+ actual.thread());113}114115return success;116}117118protected void compare(List<MonitorInfo> actualData, List<DebugMonitorInfo> expectedData) {119boolean success = true;120121// compare total amount of monitors122if (actualData.size() != expectedData.size()) {123setSuccess(false);124success = false;125log.complain("Number of expected monitors and actual ones differs");126log.complain("Expected: " + expectedData.size() + ", actual: " + actualData.size());127}128129// check that all expected monitors are contained in 'actualData'130for (DebugMonitorInfo expectedMonitorInfo : expectedData) {131boolean isMonitorFound = false;132133for (MonitorInfo actualMonitorInfo : actualData) {134if (expectedMonitorInfo.monitor.equals(actualMonitorInfo.monitor())) {135isMonitorFound = true;136137if (!compare(actualMonitorInfo, expectedMonitorInfo))138success = false;139140break;141}142}143144if (!isMonitorFound) {145setSuccess(false);146success = false;147log.complain("Expected monitor not found in result of ownedMonitorsAndFrames(): " + expectedMonitorInfo.monitor);148}149}150151// check that all monitors from 'actualData' are contained in152// 'expectedData'153for (MonitorInfo actualMonitorInfo : actualData) {154boolean isMonitorFound = false;155156for (DebugMonitorInfo expectedMonitorInfo : expectedData) {157if (actualMonitorInfo.monitor().equals(expectedMonitorInfo.monitor)) {158isMonitorFound = true;159break;160}161}162163if (!isMonitorFound) {164setSuccess(false);165success = false;166log.complain("Unexpected monitor in result of ownedMonitorsAndFrames(): " + actualMonitorInfo.monitor() + " Depth: "167+ actualMonitorInfo.stackDepth() + " Thread: " + actualMonitorInfo.thread());168}169}170171if (!success)172logDebugInfo(actualData, expectedData);173}174175private void logDebugInfo(List<MonitorInfo> actualData, List<DebugMonitorInfo> expectedData) {176log.display("ACTUAL MONITORS (total " + actualData.size() + "):");177178ThreadReference thread = null;179180for (MonitorInfo monitorInfo : actualData) {181log.display("Monitor: " + monitorInfo.monitor());182log.display("Depth: " + monitorInfo.stackDepth());183log.display("Thread: " + monitorInfo.thread());184if (thread == null)185thread = monitorInfo.thread();186}187188log.display("EXPECTED MONITORS (total " + expectedData.size() + "):");189190for (DebugMonitorInfo monitorInfo : expectedData) {191log.display("Monitor: " + monitorInfo.monitor);192log.display("Depth: " + monitorInfo.stackDepth);193log.display("Thread: " + monitorInfo.thread);194if (thread == null)195thread = monitorInfo.thread;196}197198if (thread != null) {199try {200log.display("Thread frames:");201for (StackFrame frame : thread.frames()) {202Location location = frame.location();203log.display(location.declaringType().name() + "." + location.method().name() + ", line: " + location.lineNumber());204}205} catch (Exception e) {206unexpectedException(e);207}208}209}210211/*212* Check that ThreadReference.ownedMonitorsAndFrames() returns correct213* data before calling this method debuggee should save information about214* acquired monitors in special array 'monitorsInfo',215* debugger forces debuggee to do it using command 'COMMAND_UPDATE_MONITOR_INFO'216*/217protected void checkMonitorInfo(ThreadReference threadReference) {218List<MonitorInfo> actualData = null;219220try {221actualData = threadReference.ownedMonitorsAndFrames();222} catch (Exception e) {223setSuccess(false);224log.complain("Unexpected exception: " + e);225e.printStackTrace(log.getOutStream());226}227228List<DebugMonitorInfo> expectedData = getDebugMonitorsInfo();229230compare(actualData, expectedData);231}232233}234235236