Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace008.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*/222324/*25* @test26* @key stress27*28* @summary converted from VM testbase nsk/stress/strace/strace008.29* VM testbase keywords: [stress, quick, strace]30* VM testbase readme:31* DESCRIPTION32* The test runs many threads, that recursively invoke a native method.33* After arriving at defined depth of recursion, the test calls34* java.lang.Thread.getStackTrace() and java.lang.Thread.getAllStackTraces()35* methods and checks their results. All threads are running in a loop36* as long as these methods are executed.37* The test fails if:38* - amount of stack trace elements and stack trace elements themselves are39* the same for both methods;40* - there is at least one element corresponding to invocation of unexpected41* method. Expected methods are Thread.sleep(), Thread.run() and the42* recursive method.43* This test is almost the same as nsk.stress.strace.strace007 except for44* the recursive method is a native one.45*46* @library /vmTestbase47* /test/lib48* @run main/othervm/native nsk.stress.strace.strace00849*/5051package nsk.stress.strace;5253import nsk.share.ArgumentParser;54import nsk.share.Log;5556import java.io.PrintStream;57import java.util.Map;5859/**60* The test runs <code>THRD_COUNT</code> instances of <code>strace008Thread</code>,61* that recursively invoke a native method. After arriving at defined depth62* <code>DEPTH</code> of recursion, the test calls63* <code>java.lang.Thread.getStackTrace()</code> and64* <code>java.lang.Thread.getAllStackTraces()</code> methods and checks their results.65* <p>66* It is expected that these methods return the same stack traces. Each stack frame67* for both stack traces must be corresponded to invocation of one of the methods68* defined by the <code>EXPECTED_METHODS</code> array.</p>69*/70public class strace008 {7172static final int DEPTH = 100;73static final int THRD_COUNT = 50;74static final int SLEEP_TIME = 50;75static final String NATIVE_LIB = "strace008";76static final String[] EXPECTED_METHODS = {77"java.lang.Thread.sleep",78"nsk.stress.strace.strace008Thread.run",79"nsk.stress.strace.strace008Thread.recursiveMethod"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 strace008Thread[] 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 strace008Thread[THRD_COUNT];123achivedCount = 0;124125String tmp_name;126display("starting threads...");127for (int i = 0; i < THRD_COUNT; i++) {128tmp_name = "strace008Thread" + Integer.toString(i);129threads[i] = new strace008Thread(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;218/* try {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) {226display(e);227}228*/229isSnapshotDone = false;230}231232static void display(String message) {233log.display(message);234}235236static void complain(String message) {237log.complain(message);238}239240}241242class strace008Thread extends Thread {243244private int currentDepth = 0;245246static {247try {248System.loadLibrary(strace008.NATIVE_LIB);249} catch (UnsatisfiedLinkError e) {250System.err.println("Could not load strace008 library");251System.err.println("java.library.path:"252+ System.getProperty("java.library.path"));253throw e;254}255}256257strace008Thread(String name) {258setName(name);259}260261public void run() {262263recursiveMethod();264265}266267native void recursiveMethod();268}269270271