Path: blob/master/test/hotspot/jtreg/serviceability/tmtools/jstack/TraveledLockTest.java
41153 views
/*1* Copyright (c) 2015, 2017, 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*/2223/*24* @test25* @summary Create a thread which stops in methods a(), a()->b(), a()->b()->c(),26* synchronizing on one monitor inside of each method.27* After checking that lock info is correct free the lock and28* invoke another method. Repeat this action.29* @modules java.base/jdk.internal.misc30* @library /test/lib31* @library ../share32* @run main/othervm -XX:+UsePerfData TraveledLockTest33*/34import common.ToolResults;35import java.util.Iterator;36import utils.*;3738class TraveledLockDebuggee extends Thread {3940static final String THREAD_NAME = "MyThread";4142TraveledLockDebuggee() {43setName(THREAD_NAME);44}4546Object monitor = new Object();4748public void c() {49synchronized (monitor) {50Utils.sleep();51}52}5354public void b() {55try {56synchronized (monitor) {57while (true) {58Thread.sleep(Long.MAX_VALUE);59}60}61} catch (InterruptedException e) {62c();63}64}6566public void a() {67try {68synchronized (monitor) {69while (true) {70Thread.sleep(Long.MAX_VALUE);71}72}73} catch (InterruptedException e) {74b();75}76}7778public void run() {79a();80}8182}8384public class TraveledLockTest {8586public static void main(String[] args) throws Exception {87new TraveledLockTest().doTest();88}8990private void doTest() throws Exception {91TraveledLockDebuggee debuggee = new TraveledLockDebuggee();9293// Start in method a()94debuggee.start();9596// Collect output from the jstack tool97JstackTool jstackTool = new JstackTool(ProcessHandle.current().pid());98ToolResults results1 = jstackTool.measure();99100// Go to method b()101debuggee.interrupt();102103// Collect output from the jstack tool104ToolResults results2 = jstackTool.measure();105106// Go to method c()107debuggee.interrupt();108109// Collect output from the jstack tool110ToolResults results3 = jstackTool.measure();111112analyse(results1.getStdoutString(), results2.getStdoutString(), results3.getStdoutString());113}114115// Analyzsing the outputs from the 3 jstack runs116public void analyse(String results1, String results2, String results3) {117118String jstackStr1 = results1;119String jstackStr2 = results2;120String jstackStr3 = results3;121122if (jstackStr1 == null) {123throw new RuntimeException("First jstack output is empty");124}125if (jstackStr2 == null) {126throw new RuntimeException("Second jstack output is empty");127}128if (jstackStr3 == null) {129throw new RuntimeException("Third jstack output is empty");130}131132Format format = new DefaultFormat();133JStack jstack1 = format.parse(jstackStr1);134JStack jstack2 = format.parse(jstackStr2);135JStack jstack3 = format.parse(jstackStr3);136137ThreadStack ts1 = jstack1.getThreadStack(TraveledLockDebuggee.THREAD_NAME);138ThreadStack ts2 = jstack2.getThreadStack(TraveledLockDebuggee.THREAD_NAME);139ThreadStack ts3 = jstack3.getThreadStack(TraveledLockDebuggee.THREAD_NAME);140141if (ts1 == null || ts2 == null || ts3 == null) {142throw new RuntimeException(143"One of thread stack trace is null in the first jstack output : "144+ ts1 + ", " + ts2 + ", " + ts3);145}146147MonitorInfo monitorInfo1 = null;148MonitorInfo monitorInfo2 = null;149MonitorInfo monitorInfo3 = null;150151Iterator<MethodInfo> it = ts1.getStack().iterator();152while (it.hasNext()) {153MethodInfo mi = it.next();154if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".a")) {155monitorInfo1 = haveToHaveOneLock(mi);156}157}158159it = ts2.getStack().iterator();160while (it.hasNext()) {161MethodInfo mi = it.next();162if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".a")) {163haveToBeEmpty(mi);164} else if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".b")) {165monitorInfo2 = haveToHaveOneLock(mi);166}167}168169it = ts3.getStack().iterator();170while (it.hasNext()) {171MethodInfo mi = it.next();172if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".a")173|| mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".b")) {174haveToBeEmpty(mi);175} else if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".c")) {176monitorInfo3 = haveToHaveOneLock(mi);177}178}179180System.out.println("All monitors found - passed");181}182183private MonitorInfo haveToHaveOneLock(MethodInfo mi) {184if (mi.getLocks().size() == 1) {185System.out.println("Method \"" + mi.getName()186+ "\" contain 1 lock - correct");187return mi.getLocks().getFirst();188} else {189throw new RuntimeException("Lock count ("190+ mi.getLocks().size() + ") is incorrect in method \""191+ mi.getName() + "\"");192}193}194195private void haveToBeEmpty(MethodInfo mi) {196if (mi.getLocks().size() == 0) {197System.out.println("Method \"" + mi.getName()198+ "\" does not lock anything - correct");199} else {200throw new RuntimeException(201"Unexpected lock found in method \"" + mi.getName() + "\"");202}203}204205}206207208