Path: blob/master/test/hotspot/jtreg/serviceability/tmtools/jstack/SpreadLockTest.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 invoke another method28* and get the lock again. Repeat this action.29* @modules java.base/jdk.internal.misc30* @library /test/lib31* @library ../share32* @run main/othervm -XX:+UsePerfData SpreadLockTest33*/34import common.ToolResults;35import java.util.Iterator;36import utils.*;3738class SpreadLockDebuggee extends Thread {3940static final String THREAD_NAME = "MyThread";4142SpreadLockDebuggee() {43setName(THREAD_NAME);44}4546Object monitor = new Object();4748public void c() {49synchronized (monitor) {50Utils.sleep();51}52}5354public void b() {55synchronized (monitor) {56try {57while (true) {58Thread.sleep(Long.MAX_VALUE);59}60} catch (InterruptedException e) {61c();62}63}64}6566public void a() {67synchronized (monitor) {68try {69while (true) {70Thread.sleep(Long.MAX_VALUE);71}72} catch (InterruptedException e) {73b();74}75}76}7778@Override79public void run() {80a();81}8283}8485public class SpreadLockTest {8687public static void main(String[] args) throws Exception {88new SpreadLockTest().doTest();89}9091private void doTest() throws Exception {92SpreadLockDebuggee debuggee = new SpreadLockDebuggee();9394// Start in method a()95debuggee.start();9697// Collect output from the jstack tool98JstackTool jstackTool = new JstackTool(ProcessHandle.current().pid());99ToolResults results1 = jstackTool.measure();100101// Go to method b()102debuggee.interrupt();103104// Collect output from the jstack tool105ToolResults results2 = jstackTool.measure();106107// Go to method c()108debuggee.interrupt();109110// Collect output from the jstack tool111ToolResults results3 = jstackTool.measure();112113analyse(results1.getStdoutString(), results2.getStdoutString(), results3.getStdoutString());114}115116// Analyzing the outputs from the 3 jstack runs117public void analyse(String result1, String result2, String result3) {118String jstackStr1 = result1;119String jstackStr2 = result2;120String jstackStr3 = result3;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(SpreadLockDebuggee.THREAD_NAME);138ThreadStack ts2 = jstack2.getThreadStack(SpreadLockDebuggee.THREAD_NAME);139ThreadStack ts3 = jstack3.getThreadStack(SpreadLockDebuggee.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[] monitorInfo = new MonitorInfo[6];148int counter = 0;149150Iterator<MethodInfo> it = ts1.getStack().iterator();151while (it.hasNext()) {152MethodInfo mi = it.next();153if (mi.getName().startsWith(SpreadLockDebuggee.class.getName() + ".a")) {154monitorInfo[counter++] = haveToHaveOneLock(mi);155}156}157158it = ts2.getStack().iterator();159while (it.hasNext()) {160MethodInfo mi = it.next();161if (mi.getName().startsWith(SpreadLockDebuggee.class.getName() + ".a")162|| mi.getName().startsWith(SpreadLockDebuggee.class.getName() + ".b")) {163monitorInfo[counter++] = haveToHaveOneLock(mi);164}165}166167it = ts3.getStack().iterator();168while (it.hasNext()) {169MethodInfo mi = it.next();170if (mi.getName().startsWith(SpreadLockDebuggee.class.getName() + ".a")171|| mi.getName().startsWith(SpreadLockDebuggee.class.getName() + ".b")172|| mi.getName().startsWith(SpreadLockDebuggee.class.getName() + ".c")) {173monitorInfo[counter++] = haveToHaveOneLock(mi);174}175}176177System.out.println("All monitors found - passed");178179}180181private MonitorInfo haveToHaveOneLock(MethodInfo mi) {182if (mi.getLocks().size() == 1) {183System.out.println("Method \"" + mi.getName()184+ "\" contain 1 lock - correct");185return mi.getLocks().getFirst();186} else {187throw new RuntimeException("Lock count ("188+ mi.getLocks().size() + ") is incorrect in method \""189+ mi.getName() + "\"");190}191}192193}194195196