1 /* 2 * Copyright (c) 2003, 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 30 extern "C" { 31 32 /* ============================================================================= */ 33 34 /* scaffold objects */ 35 static jlong timeout = 0; 36 37 /* constants */ 38 #define EVENTS_COUNT 3 39 40 /* tested events */ 41 static jvmtiEvent eventsList[EVENTS_COUNT] = { 42 JVMTI_EVENT_VM_INIT, 43 JVMTI_EVENT_THREAD_START, 44 JVMTI_EVENT_THREAD_END 45 }; 46 47 static const char* eventsNameList[EVENTS_COUNT] = { 48 "JVMTI_EVENT_VM_INIT", 49 "JVMTI_EVENT_THREAD_START", 50 "JVMTI_EVENT_THREAD_END" 51 }; 52 53 static int eventsCountList[EVENTS_COUNT]; 54 55 /* ============================================================================= */ 56 57 /** Clear events counters. */ 58 static void cleanEventCounts() { 59 int i; 60 61 for (i = 0; i < EVENTS_COUNT; i++) { 62 eventsCountList[i] = 0; 63 } 64 } 65 66 /** Check if all expected events received. */ 67 static int checkEventCounts() { 68 int success = NSK_TRUE; 69 int i; 70 71 NSK_DISPLAY0("Callbacks invoked:\n"); 72 for (i = 0; i < EVENTS_COUNT; i++) { 73 NSK_DISPLAY2(" %s: %d times\n", 74 eventsNameList[i], eventsCountList[i]); 75 } 76 77 if (eventsCountList[0] <= 0) { 78 NSK_COMPLAIN2("# No %s event callback invoked:\n" 79 "# invoked: %d times\n", 80 eventsNameList[0], eventsCountList[0]); 81 success = NSK_FALSE; 82 } 83 84 for (i = 1; i < EVENTS_COUNT; i++) { 85 if (eventsCountList[i] > 0) { 86 NSK_COMPLAIN2("# %s event callback was invoked after SetEventCallbacks(NULL):\n" 87 "# invoked: %d times\n", 88 eventsNameList[i], eventsCountList[i]); 89 success = NSK_FALSE; 90 } 91 } 92 93 return success; 94 } 95 96 /* ============================================================================= */ 97 98 /** Agent algorithm. */ 99 static void JNICALL 100 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 101 NSK_DISPLAY0("Wait for debugee to generate events\n"); 102 if (!nsk_jvmti_waitForSync(timeout)) 103 return; 104 105 NSK_DISPLAY0(">>> Testcase #3: Check if no unexpected events callbacks were invoked\n"); 106 if (!checkEventCounts()) { 107 nsk_jvmti_setFailStatus(); 108 } 109 110 NSK_DISPLAY0("Disable events\n"); 111 nsk_jvmti_enableEvents(JVMTI_DISABLE, EVENTS_COUNT, eventsList, NULL); 112 113 NSK_DISPLAY0("Let debugee to finish\n"); 114 if (!nsk_jvmti_resumeSync()) 115 return; 116 } 117 118 /* ============================================================================= */ 119 120 /** 121 * Callback for THREAD_START event. 122 */ 123 JNIEXPORT void JNICALL 124 callbackThreadStart(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) { 125 NSK_DISPLAY1(" <THREAD_START>: thread: 0x%p\n", (void*)thread); 126 eventsCountList[1]++; 127 } 128 129 /** 130 * Callback for THREAD_END event. 131 */ 132 JNIEXPORT void JNICALL 133 callbackThreadEnd(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) { 134 NSK_DISPLAY1(" <THREAD_END>: thread: 0x%p\n", (void*)thread); 135 eventsCountList[2]++; 136 } 137 138 /** 139 * Callback for VM_INIT event. 140 */ 141 JNIEXPORT void JNICALL 142 callbackVMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) { 143 NSK_DISPLAY1(" <VM_INIT>: thread: 0x%p\n", (void*)thread); 144 eventsCountList[0]++; 145 146 NSK_DISPLAY0(">>> Testcase #2: Set NULL for events callbacks\n"); 147 { 148 if (!NSK_JVMTI_VERIFY( 149 NSK_CPP_STUB3(SetEventCallbacks, jvmti, NULL, 0))) { 150 nsk_jvmti_setFailStatus(); 151 } 152 153 nsk_jvmti_enableEvents(JVMTI_ENABLE, EVENTS_COUNT - 1, eventsList + 1, NULL); 154 } 155 } 156 157 /* ============================================================================= */ 158 159 /** Agent library initialization. */ 160 #ifdef STATIC_BUILD 161 JNIEXPORT jint JNICALL Agent_OnLoad_setevntcallb002(JavaVM *jvm, char *options, void *reserved) { 162 return Agent_Initialize(jvm, options, reserved); 163 } 164 JNIEXPORT jint JNICALL Agent_OnAttach_setevntcallb002(JavaVM *jvm, char *options, void *reserved) { 165 return Agent_Initialize(jvm, options, reserved); 166 } 167 JNIEXPORT jint JNI_OnLoad_setevntcallb002(JavaVM *jvm, char *options, void *reserved) { 168 return JNI_VERSION_1_8; 169 } 170 #endif 171 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 172 jvmtiEnv* jvmti = NULL; 173 174 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 175 return JNI_ERR; 176 177 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 178 179 if (!NSK_VERIFY((jvmti = 180 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 181 return JNI_ERR; 182 183 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 184 return JNI_ERR; 185 186 NSK_DISPLAY0(">>> Testcase #1: Set callbacks for all tested events\n"); 187 { 188 jvmtiEventCallbacks eventCallbacks; 189 190 cleanEventCounts(); 191 192 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 193 eventCallbacks.VMInit = callbackVMInit; 194 eventCallbacks.ThreadStart = callbackThreadStart; 195 eventCallbacks.ThreadEnd = callbackThreadEnd; 196 if (!NSK_JVMTI_VERIFY( 197 NSK_CPP_STUB3(SetEventCallbacks, jvmti, 198 &eventCallbacks, sizeof(eventCallbacks)))) { 199 nsk_jvmti_setFailStatus(); 200 } else { 201 nsk_jvmti_enableEvents(JVMTI_ENABLE, 1, eventsList, NULL); 202 } 203 } 204 return JNI_OK; 205 } 206 207 /* ============================================================================= */ 208 209 }