Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace007.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/strace007.28* VM testbase keywords: [stress, quick, strace]29* VM testbase readme:30* DESCRIPTION31* The test runs many threads, that recursively invoke a pure java method.32* After arriving at defined depth of recursion, the test calls33* java.lang.Thread.getStackTrace() and java.lang.Thread.getAllStackTraces()34* methods and checks their results. All threads are running in a loop35* 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*43* @library /vmTestbase44* /test/lib45* @run main/othervm nsk.stress.strace.strace00746*/4748package nsk.stress.strace;4950import nsk.share.ArgumentParser;51import nsk.share.Log;5253import java.io.PrintStream;54import java.util.Map;5556/**57* The test runs <code>THRD_COUNT</code> instances of <code>strace007Thread</code>,58* that recursively invoke a pure java method. After arriving at defined depth59* <code>DEPTH</code> of recursion, the test calls60* <code>java.lang.Thread.getStackTrace()</code> and61* <code>java.lang.Thread.getAllStackTraces()</code> methods and checks their results.62* <p>63* <p>It is expected that these methods return the same stack traces. Each stack frame64* for both stack traces must be corresponded to invocation of one of the methods65* defined by the <code>EXPECTED_METHODS</code> array.</p>66*/67public class strace007 {6869static final int DEPTH = 500;70static final int THRD_COUNT = 100;71static final int SLEEP_TIME = 50;72static final String[] EXPECTED_METHODS = {73"java.lang.Thread.sleep",74"nsk.stress.strace.strace007Thread.run",75"nsk.stress.strace.strace007Thread.recursiveMethod"76};777879static PrintStream out;80static long waitTime = 2;8182static Object doSnapshot = new Object();83static volatile boolean isSnapshotDone = false;84static volatile int achivedCount = 0;85static Log log;8687static strace007Thread[] threads;8889public static void main(String[] args) {90out = System.out;91int exitCode = run(args);92System.exit(exitCode + 95);93}9495public static int run(String[] args) {96ArgumentParser argHandler = new ArgumentParser(args);97log = new Log(out, argHandler);98waitTime = argHandler.getWaitTime() * 60000;99100boolean res = true;101102startThreads();103104res = makeSnapshot();105106finishThreads();107108if (!res) {109complain("***>>>Test failed<<<***");110return 2;111}112113display(">>>Test passed<<<");114return 0;115}116117static void startThreads() {118threads = new strace007Thread[THRD_COUNT];119achivedCount = 0;120121String tmp_name;122display("starting threads...");123for (int i = 0; i < THRD_COUNT; i++) {124tmp_name = "strace007Thread" + Integer.toString(i);125threads[i] = new strace007Thread(tmp_name);126threads[i].start();127}128129display("waiting for the defined recursion depth ...");130while (achivedCount < THRD_COUNT) {131synchronized (doSnapshot) {132try {133doSnapshot.wait(1);134} catch (InterruptedException e) {135complain("" + e);136}137}138}139}140141static boolean makeSnapshot() {142143display("making all threads snapshots...");144Map traces = Thread.getAllStackTraces();145int count = ((StackTraceElement[]) traces.get(threads[0])).length;146147display("making snapshots of each thread...");148StackTraceElement[][] elements = new StackTraceElement[THRD_COUNT][];149for (int i = 0; i < THRD_COUNT; i++) {150elements[i] = threads[i].getStackTrace();151}152153display("checking lengths of stack traces...");154StackTraceElement[] all;155for (int i = 1; i < THRD_COUNT; i++) {156all = (StackTraceElement[]) traces.get(threads[i]);157int k = all.length;158if (count - k > 2) {159complain("wrong lengths of stack traces:\n\t"160+ threads[0].getName() + ": " + count161+ "\t"162+ threads[i].getName() + ": " + k);163return false;164}165}166167display("checking stack traces...");168boolean res = true;169for (int i = 0; i < THRD_COUNT; i++) {170all = (StackTraceElement[]) traces.get(threads[i]);171if (!checkTraces(threads[i].getName(), elements[i], all)) {172res = false;173}174}175return res;176}177178static boolean checkTraces(String threadName, StackTraceElement[] threadSnap,179StackTraceElement[] allSnap) {180181int checkedLength = threadSnap.length < allSnap.length ?182threadSnap.length : allSnap.length;183boolean res = true;184185for (int j = 0; j < checkedLength; j++) {186if (!checkElement(threadSnap[j])) {187complain("Unexpected " + j + "-element:");188complain("\tmethod name: " + threadSnap[j].getMethodName());189complain("\tclass name: " + threadSnap[j].getClassName());190if (threadSnap[j].isNativeMethod()) {191complain("\tline number: (native method)");192} else {193complain("\tline number: " + threadSnap[j].getLineNumber());194complain("\tfile name: " + threadSnap[j].getFileName());195}196complain("");197res = false;198}199}200return res;201}202203static boolean checkElement(StackTraceElement element) {204String name = element.getClassName() + "." + element.getMethodName();205for (int i = 0; i < EXPECTED_METHODS.length; i++) {206if (EXPECTED_METHODS[i].compareTo(name) == 0)207return true;208}209return false;210}211212static void finishThreads() {213isSnapshotDone = true;214try {215for (int i = 0; i < threads.length; i++) {216if (threads[i].isAlive()) {217display("waiting for finish " + threads[i].getName());218threads[i].join(waitTime);219}220}221} catch (InterruptedException e) {222complain("" + e);223}224isSnapshotDone = false;225}226227static void display(String message) {228log.display(message);229}230231static void complain(String message) {232log.complain(message);233}234235}236237class strace007Thread extends Thread {238239private int currentDepth = 0;240241static int[] arr = new int[1000];242243strace007Thread(String name) {244setName(name);245}246247public void run() {248try {249recursiveMethod(arr);250} catch (Throwable throwable) {251System.err.println("# ERROR: " + getName() + ": " + throwable);252System.exit(1);253}254}255256void recursiveMethod(int[] arr) {257currentDepth++;258259if (strace007.DEPTH - currentDepth > 0) {260recursiveMethod(arr);261}262263if (strace007.DEPTH == currentDepth) {264265synchronized (strace007.doSnapshot) {266strace007.achivedCount++;267strace007.doSnapshot.notify();268}269270while (!strace007.isSnapshotDone) {271try {272sleep(strace007.SLEEP_TIME);273} catch (InterruptedException e) {274strace007.complain(getName() + "> " + e);275}276}277}278279currentDepth--;280}281}282283284