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 for (i = 0; i < EVENTS_COUNT; i++) { 78 if (eventsCountList[i] <= 0) { 79 NSK_COMPLAIN2("# No %s event callback invoked:\n" 80 "# invoked: %d times\n", 81 eventsNameList[i], eventsCountList[i]); 82 success = NSK_FALSE; 83 } 84 } 85 86 return success; 87 } 88 89 /* ============================================================================= */ 90 91 /** Agent algorithm. */ 92 static void JNICALL 93 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 94 NSK_DISPLAY0("Wait for debugee to generate events\n"); 95 if (!nsk_jvmti_waitForSync(timeout)) 96 return; 97 98 NSK_DISPLAY0(">>> Testcase #3: Check if all events callbacks were invoked\n"); 99 if (!checkEventCounts()) { 100 nsk_jvmti_setFailStatus(); 101 } 102 103 NSK_DISPLAY0("Disable events\n"); 104 nsk_jvmti_enableEvents(JVMTI_DISABLE, EVENTS_COUNT, eventsList, NULL); 105 106 NSK_DISPLAY0("Let debugee to finish\n"); 107 if (!nsk_jvmti_resumeSync()) 108 return; 109 } 110 111 /* ============================================================================= */ 112 113 /** 114 * Callback for THREAD_START event. 115 */ 116 JNIEXPORT void JNICALL 117 callbackThreadStart(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) { 118 NSK_DISPLAY1(" <THREAD_START>: thread: 0x%p\n", (void*)thread); 119 eventsCountList[1]++; 120 } 121 122 /** 123 * Callback for THREAD_END event. 124 */ 125 JNIEXPORT void JNICALL 126 callbackThreadEnd(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) { 127 NSK_DISPLAY1(" <THREAD_END>: thread: 0x%p\n", (void*)thread); 128 eventsCountList[2]++; 129 } 130 131 /** 132 * Callback for VM_INIT event. 133 */ 134 JNIEXPORT void JNICALL 135 callbackVMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) { 136 NSK_DISPLAY1(" <VM_INIT>: thread: 0x%p\n", (void*)thread); 137 eventsCountList[0]++; 138 139 NSK_DISPLAY0(">>> Testcase #2: Set callbacks for THREAD_START and THREAD_END events\n"); 140 { 141 jvmtiEventCallbacks eventCallbacks; 142 143 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 144 eventCallbacks.ThreadStart = callbackThreadStart; 145 eventCallbacks.ThreadEnd = callbackThreadEnd; 146 if (!NSK_JVMTI_VERIFY( 147 NSK_CPP_STUB3(SetEventCallbacks, jvmti, 148 &eventCallbacks, sizeof(eventCallbacks)))) { 149 nsk_jvmti_setFailStatus(); 150 } else { 151 nsk_jvmti_enableEvents(JVMTI_ENABLE, EVENTS_COUNT - 1, eventsList + 1, NULL); 152 } 153 } 154 } 155 156 /* ============================================================================= */ 157 158 /** Agent library initialization. */ 159 #ifdef STATIC_BUILD 160 JNIEXPORT jint JNICALL Agent_OnLoad_setevntcallb001(JavaVM *jvm, char *options, void *reserved) { 161 return Agent_Initialize(jvm, options, reserved); 162 } 163 JNIEXPORT jint JNICALL Agent_OnAttach_setevntcallb001(JavaVM *jvm, char *options, void *reserved) { 164 return Agent_Initialize(jvm, options, reserved); 165 } 166 JNIEXPORT jint JNI_OnLoad_setevntcallb001(JavaVM *jvm, char *options, void *reserved) { 167 return JNI_VERSION_1_8; 168 } 169 #endif 170 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 171 jvmtiEnv* jvmti = NULL; 172 173 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 174 return JNI_ERR; 175 176 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 177 178 if (!NSK_VERIFY((jvmti = 179 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 180 return JNI_ERR; 181 182 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 183 return JNI_ERR; 184 185 NSK_DISPLAY0(">>> Testcase #1: Set callbacks for VM_INIT event\n"); 186 { 187 jvmtiEventCallbacks eventCallbacks; 188 189 cleanEventCounts(); 190 191 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 192 eventCallbacks.VMInit = callbackVMInit; 193 if (!NSK_JVMTI_VERIFY( 194 NSK_CPP_STUB3(SetEventCallbacks, jvmti, 195 &eventCallbacks, sizeof(eventCallbacks)))) { 196 nsk_jvmti_setFailStatus(); 197 } else { 198 nsk_jvmti_enableEvents(JVMTI_ENABLE, 1, eventsList, NULL); 199 } 200 } 201 return JNI_OK; 202 } 203 204 /* ============================================================================= */ 205 206 }