Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace010.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/strace010.28* VM testbase keywords: [stress, 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, each thread is blocked33* on entering a monitor. Then the test calls java.lang.Thread.getStackTrace()34* and java.lang.Thread.getAllStackTraces() methods and checks their results.35* The test fails if:36* - amount of stack trace elements and stack trace elements themselves are37* the same for both methods;38* - there is at least one element corresponding to invocation of unexpected39* method. Expected methods are Thread.sleep(), Thread.run() and the40* recursive method.41*42* @library /vmTestbase43* /test/lib44* @run main/othervm nsk.stress.strace.strace01045*/4647package nsk.stress.strace;4849import nsk.share.ArgumentParser;50import nsk.share.Failure;51import nsk.share.Log;5253import java.io.PrintStream;54import java.util.Map;5556/**57* The test runs <code>THRD_COUNT</code> instances of <code>strace010Thread</code>,58* that recursively invoke a pure java method. After arriving at defined depth59* <code>DEPTH</code> of recursion, each thread is blocked on entering a monitor.60* Then the test calls <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 strace010 {6869static final int DEPTH = 500;70static final int THRD_COUNT = 100;71static final String[] EXPECTED_METHODS = {72"java.lang.Thread.sleep",73"nsk.stress.strace.strace010Thread.run",74"nsk.stress.strace.strace010Thread.recursiveMethod"75};767778static PrintStream out;79static long waitTime = 2;8081static Object lockedObject = new Object();82static volatile boolean isLocked = false;8384volatile int achivedCount = 0;85strace010Thread[] threads;86static Log log;8788public static void main(String[] args) {89out = System.out;90int exitCode = run(args);91System.exit(exitCode + 95);92}9394public static int run(String[] args) {95ArgumentParser argHandler = new ArgumentParser(args);96log = new Log(out, argHandler);97waitTime = argHandler.getWaitTime() * 60000;9899strace010 test = new strace010();100boolean res = true;101102test.startThreads();103104res = test.makeSnapshot();105106test.finishThreads();107108if (!res) {109complain("***>>>Test failed<<<***");110return 2;111}112113display(">>>Test passed<<<");114return 0;115}116117void startThreads() {118threads = new strace010Thread[THRD_COUNT];119achivedCount = 0;120121String tmp_name;122display("starting threads...");123for (int i = 0; i < THRD_COUNT; i++) {124tmp_name = "strace010Thread" + Integer.toString(i);125threads[i] = new strace010Thread(this, tmp_name);126threads[i].start();127}128129waitFor("the defined recursion depth ...");130}131132void waitFor(String msg) {133if (msg.length() > 0)134display("waiting for " + msg);135136while (achivedCount < THRD_COUNT) {137try {138Thread.sleep(1);139} catch (InterruptedException e) {140complain("" + e);141}142}143achivedCount = 0;144}145146boolean makeSnapshot() {147148Map traces = null;149int count = 0;150StackTraceElement[][] elements = null;151152display("locking object...");153synchronized (strace010.lockedObject) {154isLocked = true;155synchronized (this) {156notifyAll();157}158Thread.currentThread().yield();159waitFor("");160161display("making all threads snapshots...");162traces = Thread.getAllStackTraces();163count = ((StackTraceElement[]) traces.get(threads[0])).length;164165display("making snapshots of each thread...");166elements = new StackTraceElement[THRD_COUNT][];167for (int i = 0; i < THRD_COUNT; i++) {168elements[i] = threads[i].getStackTrace();169}170}171display("object unlocked");172173display("");174175display("checking lengths of stack traces...");176StackTraceElement[] all;177for (int i = 1; i < THRD_COUNT; i++) {178all = (StackTraceElement[]) traces.get(threads[i]);179int k = all.length;180if (count - k > 2) {181complain("wrong lengths of stack traces:\n\t"182+ threads[0].getName() + ": " + count183+ "\t"184+ threads[i].getName() + ": " + k);185return false;186}187}188189display("checking stack traces...");190boolean res = true;191for (int i = 0; i < THRD_COUNT; i++) {192all = (StackTraceElement[]) traces.get(threads[i]);193if (!checkTraces(threads[i].getName(), elements[i], all)) {194res = false;195}196}197return res;198}199200boolean checkTraces(String threadName, StackTraceElement[] threadSnap,201StackTraceElement[] allSnap) {202203int checkedLength = threadSnap.length < allSnap.length ?204threadSnap.length : allSnap.length;205boolean res = true;206207for (int j = 0; j < checkedLength; j++) {208if (!checkElement(threadSnap[j])) {209complain("Unexpected " + j + "-element:");210complain("\tmethod name: " + threadSnap[j].getMethodName());211complain("\tclass name: " + threadSnap[j].getClassName());212if (threadSnap[j].isNativeMethod()) {213complain("\tline number: (native method)");214} else {215complain("\tline number: " + threadSnap[j].getLineNumber());216complain("\tfile name: " + threadSnap[j].getFileName());217}218complain("");219res = false;220}221}222return res;223}224225boolean checkElement(StackTraceElement element) {226String name = element.getClassName() + "." + element.getMethodName();227for (int i = 0; i < EXPECTED_METHODS.length; i++) {228if (EXPECTED_METHODS[i].compareTo(name) == 0)229return true;230}231return false;232}233234void finishThreads() {235try {236for (int i = 0; i < threads.length; i++) {237if (threads[i].isAlive()) {238display("waiting for finish " + threads[i].getName());239threads[i].join(waitTime);240}241}242} catch (InterruptedException e) {243complain("" + e);244}245isLocked = false;246}247248static void display(String message) {249log.display(message);250}251252static void complain(String message) {253log.complain(message);254}255256}257258class strace010Thread extends Thread {259260private int currentDepth = 0;261262static int[] arr = new int[1000];263strace010 test;264265strace010Thread(strace010 test, String name) {266this.test = test;267setName(name);268}269270public void run() {271try {272recursiveMethod(arr);273} catch (Throwable throwable) {274System.err.println("# ERROR: " + getName() + ": " + throwable);275System.exit(1);276}277}278279void recursiveMethod(int[] arr) {280currentDepth++;281282if (strace010.DEPTH - currentDepth > 0) {283recursiveMethod(arr);284}285286if (strace010.DEPTH == currentDepth) {287288synchronized (test) {289test.achivedCount++;290}291292int alltime = 0;293while (!test.isLocked) {294synchronized (test) {295try {296test.wait(1);297alltime++;298} catch (InterruptedException e) {299strace010.complain("" + e);300}301if (alltime > strace010.waitTime) {302throw new Failure("out of wait time");303}304}305}306307strace010.display(getName() + ">entering to monitor");308synchronized (test) {309test.achivedCount++;310}311synchronized (strace010.lockedObject) {312strace010.display(getName() + ">exiting from monitor");313}314}315316currentDepth--;317}318}319320321