Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace009.java
41155 views
/*1* Copyright (c) 2003, 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*/2223/*24* @test25* @key stress26*27* @summary converted from VM testbase nsk/stress/strace/strace009.28* VM testbase keywords: [stress, quick, strace]29* VM testbase readme:30* DESCRIPTION31* The test runs many threads, that recursively invoke pure java and native32* method by turns. After arriving at defined depth of recursion, the test33* calls java.lang.Thread.getStackTrace() and34* java.lang.Thread.getAllStackTraces() methods and checks their results.35* All threads are running in a loop as long as these methods are executed.36* The test fails if:37* - amount of stack trace elements and stack trace elements themselves are38* the same for both methods;39* - there is at least one element corresponding to invocation of unexpected40* method. Expected methods are Thread.sleep(), Thread.run() and the41* recursive method.42* This test is almost the same as nsk.stress.strace.strace007 except for43* recursion is presented by pure java and native method invocation.44*45* @library /vmTestbase46* /test/lib47* @run main/othervm/native nsk.stress.strace.strace00948*/4950package nsk.stress.strace;5152import nsk.share.ArgumentParser;53import nsk.share.Log;5455import java.io.PrintStream;56import java.util.Map;5758/**59* The test runs <code>THRD_COUNT</code> instances of <code>strace009Thread</code>,60* that recursively invoke pure java and native method by turns. After arriving at61* defined depth <code>DEPTH</code> of recursion, the test calls62* <code>java.lang.Thread.getStackTrace()</code> and63* <code>java.lang.Thread.getAllStackTraces()</code> methods and checks their results.64* <p>65* It is expected that these methods return the same stack traces. Each stack frame66* for both stack traces must be corresponded to invocation of one of the methods67* defined by the <code>EXPECTED_METHODS</code> array.</p>68*/69public class strace009 {7071static final int DEPTH = 200;72static final int THRD_COUNT = 100;73static final String NATIVE_LIB = "strace009";74static final int SLEEP_TIME = 50;75static final String[] EXPECTED_METHODS = {76"java.lang.Thread.sleep",77"nsk.stress.strace.strace009Thread.run",78"nsk.stress.strace.strace009Thread.recursiveMethod1",79"nsk.stress.strace.strace009Thread.recursiveMethod2"80};818283static long waitTime = 2;8485static Object doSnapshot = new Object();86static volatile boolean isSnapshotDone = false;87static volatile int achivedCount = 0;88static PrintStream out;89static Log log;9091static strace009Thread[] threads;9293public static void main(String[] args) {94out = System.out;95int exitCode = run(args);96System.exit(exitCode + 95);97}9899public static int run(String[] args) {100ArgumentParser argHandler = new ArgumentParser(args);101log = new Log(out, argHandler);102waitTime = argHandler.getWaitTime() * 60000;103104boolean res = true;105106startThreads();107108res = makeSnapshot();109110finishThreads();111112if (!res) {113complain("***>>>Test failed<<<***");114return 2;115}116117display(">>>Test passed<<<");118return 0;119}120121static void startThreads() {122threads = new strace009Thread[THRD_COUNT];123achivedCount = 0;124125String tmp_name;126display("starting threads...");127for (int i = 0; i < THRD_COUNT; i++) {128tmp_name = "strace009Thread" + Integer.toString(i);129threads[i] = new strace009Thread(tmp_name);130threads[i].start();131}132133display("waiting for the defined recursion depth ...");134while (achivedCount < THRD_COUNT) {135synchronized (doSnapshot) {136try {137doSnapshot.wait(1);138} catch (InterruptedException e) {139complain("" + e);140}141}142}143}144145static boolean makeSnapshot() {146147display("making all threads snapshots...");148Map traces = Thread.getAllStackTraces();149int count = ((StackTraceElement[]) traces.get(threads[0])).length;150151display("making snapshots of each thread...");152StackTraceElement[][] elements = new StackTraceElement[THRD_COUNT][];153for (int i = 0; i < THRD_COUNT; i++) {154elements[i] = threads[i].getStackTrace();155}156157display("checking lengths of stack traces...");158StackTraceElement[] all;159for (int i = 1; i < THRD_COUNT; i++) {160all = (StackTraceElement[]) traces.get(threads[i]);161int k = all.length;162if (count - k > 2) {163complain("wrong lengths of stack traces:\n\t"164+ threads[0].getName() + ": " + count165+ "\t"166+ threads[i].getName() + ": " + k);167return false;168}169}170171display("checking stack traces...");172boolean res = true;173for (int i = 0; i < THRD_COUNT; i++) {174all = (StackTraceElement[]) traces.get(threads[i]);175if (!checkTraces(threads[i].getName(), elements[i], all)) {176res = false;177}178}179return res;180}181182static boolean checkTraces(String threadName, StackTraceElement[] threadSnap,183StackTraceElement[] allSnap) {184185int checkedLength = threadSnap.length < allSnap.length ?186threadSnap.length : allSnap.length;187boolean res = true;188189for (int j = checkedLength; j < 0; j--) {190if (!checkElement(threadSnap[j])) {191complain("Unexpected " + j + "-element:");192complain("\tmethod name: " + threadSnap[j].getMethodName());193complain("\tclass name: " + threadSnap[j].getClassName());194if (threadSnap[j].isNativeMethod()) {195complain("\tline number: (native method)");196} else {197complain("\tline number: " + threadSnap[j].getLineNumber());198complain("\tfile name: " + threadSnap[j].getFileName());199}200complain("");201res = false;202}203}204return res;205}206207static boolean checkElement(StackTraceElement element) {208String name = element.getClassName() + "." + element.getMethodName();209for (int i = 0; i < EXPECTED_METHODS.length; i++) {210if (EXPECTED_METHODS[i].compareTo(name) == 0)211return true;212}213return false;214}215216static void finishThreads() {217isSnapshotDone = true;218try {219for (int i = 0; i < threads.length; i++) {220if (threads[i].isAlive()) {221display("waiting for finish " + threads[i].getName());222threads[i].join(waitTime);223}224}225} catch (InterruptedException e) {226complain("" + e);227}228isSnapshotDone = false;229}230231static void display(String message) {232log.display(message);233}234235static void complain(String message) {236log.complain(message);237}238239}240241class strace009Thread extends Thread {242243private int currentDepth = 0;244245static {246try {247System.loadLibrary(strace009.NATIVE_LIB);248} catch (UnsatisfiedLinkError e) {249System.err.println("Could not load " + strace009.NATIVE_LIB + " library");250System.err.println("java.library.path:"251+ System.getProperty("java.library.path"));252throw e;253}254}255256strace009Thread(String name) {257setName(name);258}259260public void run() {261262recursiveMethod1();263264}265266void recursiveMethod1() {267currentDepth++;268269if (strace009.DEPTH - currentDepth > 0) {270recursiveMethod2();271}272273if (strace009.DEPTH >= currentDepth) {274275synchronized (strace009.doSnapshot) {276strace009.achivedCount++;277strace009.doSnapshot.notify();278}279280while (!strace009.isSnapshotDone) {281try {282sleep(strace009.SLEEP_TIME);283} catch (InterruptedException e) {284strace009.complain(getName() + "> " + e);285}286}287}288289currentDepth--;290}291292native void recursiveMethod2();293}294295296