1 /* 2 * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include <string.h> 25 #include "jvmti.h" 26 #include "agent_common.h" 27 #include "jni_tools.h" 28 #include "jvmti_tools.h" 29 #include "JVMTITools.h" 30 31 extern "C" { 32 33 /* ============================================================================= */ 34 35 /* scaffold objects */ 36 static jvmtiEnv *jvmti = NULL; 37 static jlong timeout = 0; 38 39 static int eventCount = 0; 40 41 /* ============================================================================= */ 42 43 JNIEXPORT void JNICALL 44 cbThreadEnd(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread) { 45 46 eventCount++; 47 } 48 49 /* ============================================================================= */ 50 51 static int 52 enableEvent(jvmtiEventMode enable, jvmtiEvent event) { 53 54 if (enable == JVMTI_ENABLE) { 55 NSK_DISPLAY1("enabling %s\n", TranslateEvent(event)); 56 } else { 57 NSK_DISPLAY1("disabling %s\n", TranslateEvent(event)); 58 } 59 60 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(enable, event, NULL))) { 61 nsk_jvmti_setFailStatus(); 62 return NSK_FALSE; 63 } 64 65 return NSK_TRUE; 66 } 67 68 /* ============================================================================= */ 69 70 int checkEvents() { 71 72 int result = NSK_TRUE; 73 74 if (eventCount == 0) { 75 nsk_jvmti_setFailStatus(); 76 NSK_COMPLAIN0("Number of THREAD_END events must be greater than 0\n"); 77 nsk_jvmti_setFailStatus(); 78 result = NSK_FALSE; 79 } 80 81 return result; 82 } 83 84 /* ============================================================================= */ 85 86 static int 87 setCallBacks() { 88 jvmtiEventCallbacks eventCallbacks; 89 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 90 91 eventCallbacks.ThreadEnd = cbThreadEnd; 92 93 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks)))) 94 return NSK_FALSE; 95 96 return NSK_TRUE; 97 } 98 99 /* ============================================================================= */ 100 101 /** Agent algorithm. */ 102 static void JNICALL 103 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { 104 105 NSK_DISPLAY0("Wait for debuggee to become ready\n"); 106 if (!nsk_jvmti_waitForSync(timeout)) 107 return; 108 109 NSK_DISPLAY0("Let debuggee to continue\n"); 110 if (!nsk_jvmti_resumeSync()) 111 return; 112 113 if (!nsk_jvmti_waitForSync(timeout)) 114 return; 115 116 if (!checkEvents()) { 117 nsk_jvmti_setFailStatus(); 118 } 119 120 NSK_DISPLAY0("Let debuggee to finish\n"); 121 if (!nsk_jvmti_resumeSync()) 122 return; 123 124 } 125 126 /* ============================================================================= */ 127 128 /** Agent library initialization. */ 129 #ifdef STATIC_BUILD 130 JNIEXPORT jint JNICALL Agent_OnLoad_threadend002(JavaVM *jvm, char *options, void *reserved) { 131 return Agent_Initialize(jvm, options, reserved); 132 } 133 JNIEXPORT jint JNICALL Agent_OnAttach_threadend002(JavaVM *jvm, char *options, void *reserved) { 134 return Agent_Initialize(jvm, options, reserved); 135 } 136 JNIEXPORT jint JNI_OnLoad_threadend002(JavaVM *jvm, char *options, void *reserved) { 137 return JNI_VERSION_1_8; 138 } 139 #endif 140 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 141 142 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 143 return JNI_ERR; 144 145 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 146 147 if (!NSK_VERIFY((jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 148 return JNI_ERR; 149 150 if (!setCallBacks()) { 151 return JNI_ERR; 152 } 153 154 if (!enableEvent(JVMTI_ENABLE, JVMTI_EVENT_THREAD_END)) { 155 NSK_COMPLAIN0("Events could not be enabled"); 156 nsk_jvmti_setFailStatus(); 157 return JNI_ERR; 158 } 159 160 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 161 return JNI_ERR; 162 163 return JNI_OK; 164 } 165 166 }