Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace014.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/strace014.28* VM testbase keywords: [stress, strace]29* VM testbase readme:30* DESCRIPTION31* The test runs many threads, that recursively invoke a native method.32* After arriving at defined depth of recursion, each thread is switched to33* waits for 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* This test is almost the same as nsk.stress.strace.013 except for42* the recursive method is a native one.43*44* @library /vmTestbase45* /test/lib46* @run main/othervm/native nsk.stress.strace.strace01447*/4849package nsk.stress.strace;5051import nsk.share.ArgumentParser;52import nsk.share.Log;5354import java.io.PrintStream;55import java.util.Map;5657/**58* The test runs <code>THRD_COUNT</code> instances of <code>strace010Thread</code>,59* that recursively invoke a native method. After arriving at defined depth60* <code>DEPTH</code> of recursion, each thread is switched to wait a monitor.61* Then the test calls <code>java.lang.Thread.getStackTrace()</code> and62* <code>java.lang.Thread.getAllStackTraces()</code> methods and checks their results.63* <p>64* <p>It is expected that these methods return the same stack traces. Each stack frame65* for both stack traces must be corresponded to invocation of one of the methods66* defined by the <code>EXPECTED_METHODS</code> array.</p>67*/68public class strace014 {6970static final int DEPTH = 100;71static final int THRD_COUNT = 100;72static final String[] EXPECTED_METHODS = {73"java.lang.Object.wait",74"nsk.stress.strace.strace014Thread.run",75"nsk.stress.strace.strace014Thread.recursiveMethod"76};7778static PrintStream out;79static long waitTime = 2;8081static Object lockedObject = new Object();82static volatile boolean proceed = false;8384static volatile int achivedCount = 0;85strace014Thread[] 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;9899strace014 test = new strace014();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 strace014Thread[THRD_COUNT];119achivedCount = 0;120121String tmp_name;122display("starting threads...");123for (int i = 0; i < THRD_COUNT; i++) {124tmp_name = "strace014Thread" + Integer.toString(i);125threads[i] = new strace014Thread(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("making all threads snapshots...");153traces = Thread.getAllStackTraces();154count = ((StackTraceElement[]) traces.get(threads[0])).length;155156display("making snapshots of each thread...");157elements = new StackTraceElement[THRD_COUNT][];158for (int i = 0; i < THRD_COUNT; i++) {159elements[i] = threads[i].getStackTrace();160}161162163display("notifying ...");164synchronized (lockedObject) {165proceed = true;166lockedObject.notifyAll();167}168169display("");170171display("checking lengths of stack traces...");172StackTraceElement[] all;173for (int i = 1; i < THRD_COUNT; i++) {174all = (StackTraceElement[]) traces.get(threads[i]);175int k = all.length;176if (count - k > 2) {177complain("wrong lengths of stack traces:\n\t"178+ threads[0].getName() + ": " + count179+ "\t"180+ threads[i].getName() + ": " + k);181return false;182}183}184185display("checking stack traces...");186boolean res = true;187for (int i = 0; i < THRD_COUNT; i++) {188all = (StackTraceElement[]) traces.get(threads[i]);189if (!checkTraces(threads[i].getName(), elements[i], all)) {190res = false;191}192}193return res;194}195196boolean checkTraces(String threadName, StackTraceElement[] threadSnap,197StackTraceElement[] allSnap) {198199int checkedLength = threadSnap.length < allSnap.length ?200threadSnap.length : allSnap.length;201boolean res = true;202203for (int j = 0; j < checkedLength; j++) {204if (!checkElement(threadSnap[j])) {205complain("Unexpected " + j + "-element:");206complain("\tmethod name: " + threadSnap[j].getMethodName());207complain("\tclass name: " + threadSnap[j].getClassName());208if (threadSnap[j].isNativeMethod()) {209complain("\tline number: (native method)");210} else {211complain("\tline number: " + threadSnap[j].getLineNumber());212complain("\tfile name: " + threadSnap[j].getFileName());213}214complain("");215res = false;216}217}218return res;219}220221boolean checkElement(StackTraceElement element) {222String name = element.getClassName() + "." + element.getMethodName();223for (int i = 0; i < EXPECTED_METHODS.length; i++) {224if (EXPECTED_METHODS[i].compareTo(name) == 0)225return true;226}227return false;228}229230void finishThreads() {231try {232for (int i = 0; i < threads.length; i++) {233if (threads[i].isAlive()) {234display("waiting for finish " + threads[i].getName());235threads[i].join(waitTime);236}237}238} catch (InterruptedException e) {239complain("" + e);240}241}242243static void display(String message) {244log.display(message);245}246247static void complain(String message) {248log.complain(message);249}250251}252253/**254* The test creates many instances of <code>strace014Thread</code> class and tries255* to get their stack traces.256*/257class strace014Thread extends Thread {258259private int currentDepth = 0;260261strace014 test;262263static {264try {265System.loadLibrary("strace014");266} catch (UnsatisfiedLinkError e) {267System.err.println("Could not load strace014 library");268System.err.println("java.library.path:"269+ System.getProperty("java.library.path"));270throw e;271}272}273274strace014Thread(strace014 test, String name) {275this.test = test;276setName(name);277}278279public void run() {280281recursiveMethod();282283}284285native void recursiveMethod();286}287288289