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( 61 NSK_CPP_STUB4(SetEventNotificationMode, jvmti, enable, 62 event, NULL))) { 63 nsk_jvmti_setFailStatus(); 64 return NSK_FALSE; 65 } 66 67 return NSK_TRUE; 68 } 69 70 /* ============================================================================= */ 71 72 int checkEvents() { 73 74 int result = NSK_TRUE; 75 76 if (eventCount == 0) { 77 nsk_jvmti_setFailStatus(); 78 NSK_COMPLAIN0("Number of THREAD_END events must be greater than 0\n"); 79 nsk_jvmti_setFailStatus(); 80 result = NSK_FALSE; 81 } 82 83 return result; 84 } 85 86 /* ============================================================================= */ 87 88 static int 89 setCallBacks() { 90 jvmtiEventCallbacks eventCallbacks; 91 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 92 93 eventCallbacks.ThreadEnd = cbThreadEnd; 94 95 if (!NSK_JVMTI_VERIFY( 96 NSK_CPP_STUB3(SetEventCallbacks, jvmti, 97 &eventCallbacks, 98 sizeof(eventCallbacks)))) 99 return NSK_FALSE; 100 101 return NSK_TRUE; 102 } 103 104 /* ============================================================================= */ 105 106 /** Agent algorithm. */ 107 static void JNICALL 108 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { 109 110 NSK_DISPLAY0("Wait for debuggee to become ready\n"); 111 if (!nsk_jvmti_waitForSync(timeout)) 112 return; 113 114 NSK_DISPLAY0("Let debuggee to continue\n"); 115 if (!nsk_jvmti_resumeSync()) 116 return; 117 118 if (!nsk_jvmti_waitForSync(timeout)) 119 return; 120 121 if (!checkEvents()) { 122 nsk_jvmti_setFailStatus(); 123 } 124 125 NSK_DISPLAY0("Let debuggee to finish\n"); 126 if (!nsk_jvmti_resumeSync()) 127 return; 128 129 } 130 131 /* ============================================================================= */ 132 133 /** Agent library initialization. */ 134 #ifdef STATIC_BUILD 135 JNIEXPORT jint JNICALL Agent_OnLoad_threadend002(JavaVM *jvm, char *options, void *reserved) { 136 return Agent_Initialize(jvm, options, reserved); 137 } 138 JNIEXPORT jint JNICALL Agent_OnAttach_threadend002(JavaVM *jvm, char *options, void *reserved) { 139 return Agent_Initialize(jvm, options, reserved); 140 } 141 JNIEXPORT jint JNI_OnLoad_threadend002(JavaVM *jvm, char *options, void *reserved) { 142 return JNI_VERSION_1_8; 143 } 144 #endif 145 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 146 147 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 148 return JNI_ERR; 149 150 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 151 152 if (!NSK_VERIFY((jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 153 return JNI_ERR; 154 155 if (!setCallBacks()) { 156 return JNI_ERR; 157 } 158 159 if (!enableEvent(JVMTI_ENABLE, JVMTI_EVENT_THREAD_END)) { 160 NSK_COMPLAIN0("Events could not be enabled"); 161 nsk_jvmti_setFailStatus(); 162 return JNI_ERR; 163 } 164 165 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 166 return JNI_ERR; 167 168 return JNI_OK; 169 } 170 171 }