Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetAllThreads/allthr001/allthr001.cpp
40955 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#include <stdio.h>24#include <stdlib.h>25#include <string.h>26#include "jvmti.h"27#include "agent_common.h"28#include "JVMTITools.h"2930extern "C" {313233#define PASSED 034#define STATUS_FAILED 23536typedef struct {37int cnt;38const char **thrNames;39} info;4041static jvmtiEnv *jvmti;42static jrawMonitorID lock1;43static jrawMonitorID lock2;44static jboolean printdump = JNI_FALSE;45static jint result = PASSED;46static jvmtiThreadInfo inf;47static int sys_cnt;48static const char *names0[] = { "main" };49static const char *names1[] = { "main", "thread1" };50static const char *names2[] = { "main", "Thread-" };51static info thrInfo[] = {52{ 1, names0 }, { 1, names0 }, { 2, names1 }, { 1, names0 }, { 2, names2 }53};5455jthread jthr(JNIEnv *env) {56jclass thrClass;57jmethodID cid;58jthread res;59thrClass = env->FindClass("java/lang/Thread");60cid = env->GetMethodID(thrClass, "<init>", "()V");61res = env->NewObject(thrClass, cid);62return res;63}6465static void JNICALL66sys_thread(jvmtiEnv* jvmti, JNIEnv* jni, void *p) {67jvmtiError err;6869err = jvmti->RawMonitorEnter(lock2);70if (err != JVMTI_ERROR_NONE) {71printf("Failed to enter raw monitor 2 (thread): %s (%d)\n",72TranslateError(err), err);73result = STATUS_FAILED;74}7576/* allows the main thread to wait until the child thread is running */77err = jvmti->RawMonitorEnter(lock1);78if (err != JVMTI_ERROR_NONE) {79printf("Failed to enter raw monitor 1 (thread): %s (%d)\n",80TranslateError(err), err);81result = STATUS_FAILED;82}83err = jvmti->RawMonitorNotify(lock1);84if (err != JVMTI_ERROR_NONE) {85printf("Failed to notify raw monitor (thread): %s (%d)\n",86TranslateError(err), err);87result = STATUS_FAILED;88}89err = jvmti->RawMonitorExit(lock1);90if (err != JVMTI_ERROR_NONE) {91printf("Failed to exit raw monitor 1 (thread): %s (%d)\n",92TranslateError(err), err);93result = STATUS_FAILED;94}9596/* keeps the child thread from exiting */97err = jvmti->RawMonitorWait(lock2, (jlong)0);98if (err != JVMTI_ERROR_NONE) {99printf("Failed to wait raw monitor (thread): %s (%d)\n",100TranslateError(err), err);101result = STATUS_FAILED;102}103err = jvmti->RawMonitorExit(lock2);104if (err != JVMTI_ERROR_NONE) {105printf("Failed to exit raw monitor 2 (thread): %s (%d)\n",106TranslateError(err), err);107result = STATUS_FAILED;108}109}110111#ifdef STATIC_BUILD112JNIEXPORT jint JNICALL Agent_OnLoad_allthr001(JavaVM *jvm, char *options, void *reserved) {113return Agent_Initialize(jvm, options, reserved);114}115JNIEXPORT jint JNICALL Agent_OnAttach_allthr001(JavaVM *jvm, char *options, void *reserved) {116return Agent_Initialize(jvm, options, reserved);117}118JNIEXPORT jint JNI_OnLoad_allthr001(JavaVM *jvm, char *options, void *reserved) {119return JNI_VERSION_1_8;120}121#endif122jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {123jint res;124jvmtiError err;125126if (options != NULL && strcmp(options, "printdump") == 0) {127printdump = JNI_TRUE;128}129130res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);131if (res != JNI_OK || jvmti == NULL) {132printf("Wrong result of a valid call to GetEnv !\n");133return JNI_ERR;134}135136err = jvmti->CreateRawMonitor("_lock1", &lock1);137if (err != JVMTI_ERROR_NONE) {138printf("Failed to create raw monitor 1, err = %d\n", err);139return JNI_ERR;140}141142err = jvmti->CreateRawMonitor("_lock2", &lock2);143if (err != JVMTI_ERROR_NONE) {144printf("Failed to create raw monitor 2, err = %d\n", err);145return JNI_ERR;146}147148return JNI_OK;149}150151JNIEXPORT void checkInfo(JNIEnv *env, int ind) {152jint threadsCount = -1;153jthread *threads;154int i, j, found;155jvmtiError err;156int num_unexpected = 0;157158if (printdump == JNI_TRUE) {159printf(" >>> Check: %d\n", ind);160}161162if (ind == 4) {163err = jvmti->RawMonitorEnter(lock1);164if (err != JVMTI_ERROR_NONE) {165printf("Failed to enter raw monitor (check): %s (%d)\n",166TranslateError(err), err);167result = STATUS_FAILED;168}169err = jvmti->RunAgentThread(jthr(env), sys_thread, NULL,170JVMTI_THREAD_NORM_PRIORITY);171if (err != JVMTI_ERROR_NONE) {172printf("Failed to start agent thread: %s (%d)\n",173TranslateError(err), err);174result = STATUS_FAILED;175}176err = jvmti->RawMonitorWait(lock1, (jlong)0);177if (err != JVMTI_ERROR_NONE) {178printf("Failed to wait raw monitor (check): %s (%d)\n",179TranslateError(err), err);180result = STATUS_FAILED;181}182err = jvmti->RawMonitorExit(lock1);183if (err != JVMTI_ERROR_NONE) {184printf("Failed to exit raw monitor (check): %s (%d)\n",185TranslateError(err), err);186result = STATUS_FAILED;187}188}189190err = jvmti->GetAllThreads(&threadsCount, &threads);191if (err != JVMTI_ERROR_NONE) {192printf("Failed to get all threads (check): %s (%d)\n",193TranslateError(err), err);194result = STATUS_FAILED;195return;196}197198for (i = 0; i < threadsCount; i++) {199if (!isThreadExpected(jvmti, threads[i])) {200num_unexpected++;201}202}203204if (threadsCount - num_unexpected != thrInfo[ind].cnt + sys_cnt) {205printf("Point %d: number of threads expected: %d, got: %d\n",206ind, thrInfo[ind].cnt + sys_cnt, threadsCount - num_unexpected);207result = STATUS_FAILED;208return;209}210211for (i = 0; i < thrInfo[ind].cnt; i++) {212for (j = 0, found = 0; j < threadsCount && !found; j++) {213err = jvmti->GetThreadInfo(threads[j], &inf);214if (err != JVMTI_ERROR_NONE) {215printf("Failed to get thread info: %s (%d)\n",216TranslateError(err), err);217result = STATUS_FAILED;218return;219}220if (printdump == JNI_TRUE) {221printf(" >>> %s", inf.name);222}223found = (inf.name != NULL &&224strstr(inf.name, thrInfo[ind].thrNames[i]) == inf.name &&225(ind == 4 || strlen(inf.name) ==226strlen(thrInfo[ind].thrNames[i])));227}228if (printdump == JNI_TRUE) {229printf("\n");230}231if (!found) {232printf("Point %d: thread %s not detected\n",233ind, thrInfo[ind].thrNames[i]);234result = STATUS_FAILED;235}236}237238err = jvmti->Deallocate((unsigned char *)threads);239if (err != JVMTI_ERROR_NONE) {240printf("Failed to deallocate array: %s (%d)\n",241TranslateError(err), err);242result = STATUS_FAILED;243}244245if (ind == 4) {246err = jvmti->RawMonitorEnter(lock2);247if (err != JVMTI_ERROR_NONE) {248printf("Failed to enter raw monitor (check): %s (%d)\n",249TranslateError(err), err);250result = STATUS_FAILED;251}252err = jvmti->RawMonitorNotify(lock2);253if (err != JVMTI_ERROR_NONE) {254printf("Failed to notify raw monitor (check): %s (%d)\n",255TranslateError(err), err);256result = STATUS_FAILED;257}258err = jvmti->RawMonitorExit(lock2);259if (err != JVMTI_ERROR_NONE) {260printf("Failed to exit raw monitor (check): %s (%d)\n",261TranslateError(err), err);262result = STATUS_FAILED;263}264}265}266267JNIEXPORT void JNICALL Java_nsk_jvmti_GetAllThreads_allthr001_setSysCnt(JNIEnv *env, jclass cls) {268jint threadsCount = -1;269jthread *threads;270jvmtiError err;271int i;272273err = jvmti->GetAllThreads(&threadsCount, &threads);274if (err != JVMTI_ERROR_NONE) {275printf("Failed to get all threads (count): %s (%d)\n",276TranslateError(err), err);277result = STATUS_FAILED;278return;279}280281sys_cnt = threadsCount - 1;282283for (i = 0; i < threadsCount; i++) {284if (!isThreadExpected(jvmti, threads[i])) {285sys_cnt--;286}287}288289if (printdump == JNI_TRUE) {290printf(" >>> number of system threads: %d\n", sys_cnt);291}292}293294JNIEXPORT void JNICALL295Java_nsk_jvmti_GetAllThreads_allthr001_checkInfo(JNIEnv *env, jclass cls, jint ind) {296checkInfo(env, ind);297}298299JNIEXPORT jint JNICALL Java_nsk_jvmti_GetAllThreads_allthr001_getRes(JNIEnv *env, jclass cls) {300return result;301}302303}304305306