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 <stdlib.h> 25 #include <string.h> 26 #include "jvmti.h" 27 #include "agent_common.h" 28 #include "jni_tools.h" 29 #include "jvmti_tools.h" 30 31 extern "C" { 32 33 /* ============================================================================= */ 34 35 static jlong timeout = 0; 36 37 #define STATUS_FAIL 97 38 39 #define EVENTS_COUNT 2 40 41 static jvmtiEvent events[EVENTS_COUNT] = { 42 JVMTI_EVENT_VM_INIT, 43 JVMTI_EVENT_VM_DEATH 44 }; 45 46 static jvmtiCapabilities initCaps; 47 48 /* ============================================================================= */ 49 50 /** Prints capabilities structure as raw bits. */ 51 static void printRawCapabilities(const jvmtiCapabilities* caps) { 52 const unsigned char* p = (const unsigned char*)caps; 53 int size = (int) sizeof(jvmtiCapabilities); 54 int i, j, k; 55 56 nsk_printf(" "); 57 for (j = 0; j < 16; j++) { 58 nsk_printf(" %1X", j); 59 } 60 nsk_printf("\n"); 61 62 for (i = 0; i < size; i += 2) { 63 int prefix = i / 2; 64 65 nsk_printf(" 0x%03X.: ", prefix); 66 for (k = 0; k < 2; k++) { 67 unsigned char b = *(p++); 68 69 for (j = 0; j < 8; j++) { 70 int bit = b % 2; 71 b /= 2; 72 nsk_printf(" %1d", bit); 73 } 74 } 75 nsk_printf("\n"); 76 } 77 } 78 79 #define PRINT_CAP(caps, name) nsk_printf(" %-40s: %d\n", #name, (int)caps->name) 80 81 /** Print values of known capabilities. */ 82 static void printKnownCapabilities(const jvmtiCapabilities* caps) { 83 PRINT_CAP(caps, can_tag_objects); 84 PRINT_CAP(caps, can_generate_field_modification_events); 85 PRINT_CAP(caps, can_generate_field_access_events); 86 PRINT_CAP(caps, can_get_bytecodes); 87 PRINT_CAP(caps, can_get_synthetic_attribute); 88 PRINT_CAP(caps, can_get_owned_monitor_info); 89 PRINT_CAP(caps, can_get_current_contended_monitor); 90 PRINT_CAP(caps, can_get_monitor_info); 91 PRINT_CAP(caps, can_pop_frame); 92 PRINT_CAP(caps, can_redefine_classes); 93 PRINT_CAP(caps, can_signal_thread); 94 PRINT_CAP(caps, can_get_source_file_name); 95 PRINT_CAP(caps, can_get_line_numbers); 96 PRINT_CAP(caps, can_get_source_debug_extension); 97 PRINT_CAP(caps, can_access_local_variables); 98 PRINT_CAP(caps, can_maintain_original_method_order); 99 PRINT_CAP(caps, can_generate_single_step_events); 100 PRINT_CAP(caps, can_generate_exception_events); 101 PRINT_CAP(caps, can_generate_frame_pop_events); 102 PRINT_CAP(caps, can_generate_breakpoint_events); 103 PRINT_CAP(caps, can_suspend); 104 /* :1 */ 105 PRINT_CAP(caps, can_get_current_thread_cpu_time); 106 PRINT_CAP(caps, can_get_thread_cpu_time); 107 PRINT_CAP(caps, can_generate_method_entry_events); 108 PRINT_CAP(caps, can_generate_method_exit_events); 109 PRINT_CAP(caps, can_generate_all_class_hook_events); 110 PRINT_CAP(caps, can_generate_compiled_method_load_events); 111 PRINT_CAP(caps, can_generate_monitor_events); 112 PRINT_CAP(caps, can_generate_vm_object_alloc_events); 113 PRINT_CAP(caps, can_generate_native_method_bind_events); 114 PRINT_CAP(caps, can_generate_garbage_collection_events); 115 PRINT_CAP(caps, can_generate_object_free_events); 116 /* :15 */ 117 /* :16 */ 118 /* :16 */ 119 /* :16 */ 120 /* :16 */ 121 /* :16 */ 122 } 123 124 #define CHECK_CAP(initCaps, caps, name) \ 125 if (initCaps->name != caps->name) { \ 126 success = NSK_FALSE; \ 127 NSK_COMPLAIN4("GetCapabilities() in %s returned after adding empty capabilities list:" \ 128 "# capability: %s\n" \ 129 "# got value: %d\n" \ 130 "# expected: %d\n", \ 131 where, #name, (int)caps->name, initCaps->name); \ 132 } 133 134 /** 135 * Check value of known capabilities. 136 * @returns NSK_FALSE if any error occured. 137 */ 138 static int checkCapabilitiesValue(jvmtiCapabilities* caps, jvmtiCapabilities* initCaps, const char where[]) { 139 int success = NSK_TRUE; 140 141 CHECK_CAP(initCaps, caps, can_tag_objects); 142 CHECK_CAP(initCaps, caps, can_generate_field_modification_events); 143 CHECK_CAP(initCaps, caps, can_generate_field_access_events); 144 CHECK_CAP(initCaps, caps, can_get_bytecodes); 145 CHECK_CAP(initCaps, caps, can_get_synthetic_attribute); 146 CHECK_CAP(initCaps, caps, can_get_owned_monitor_info); 147 CHECK_CAP(initCaps, caps, can_get_current_contended_monitor); 148 CHECK_CAP(initCaps, caps, can_get_monitor_info); 149 CHECK_CAP(initCaps, caps, can_pop_frame); 150 CHECK_CAP(initCaps, caps, can_redefine_classes); 151 CHECK_CAP(initCaps, caps, can_signal_thread); 152 CHECK_CAP(initCaps, caps, can_get_source_file_name); 153 CHECK_CAP(initCaps, caps, can_get_line_numbers); 154 CHECK_CAP(initCaps, caps, can_get_source_debug_extension); 155 CHECK_CAP(initCaps, caps, can_access_local_variables); 156 CHECK_CAP(initCaps, caps, can_maintain_original_method_order); 157 CHECK_CAP(initCaps, caps, can_generate_single_step_events); 158 CHECK_CAP(initCaps, caps, can_generate_exception_events); 159 CHECK_CAP(initCaps, caps, can_generate_frame_pop_events); 160 CHECK_CAP(initCaps, caps, can_generate_breakpoint_events); 161 CHECK_CAP(initCaps, caps, can_suspend); 162 /* :1 */ 163 CHECK_CAP(initCaps, caps, can_get_current_thread_cpu_time); 164 CHECK_CAP(initCaps, caps, can_get_thread_cpu_time); 165 CHECK_CAP(initCaps, caps, can_generate_method_entry_events); 166 CHECK_CAP(initCaps, caps, can_generate_method_exit_events); 167 CHECK_CAP(initCaps, caps, can_generate_all_class_hook_events); 168 CHECK_CAP(initCaps, caps, can_generate_compiled_method_load_events); 169 CHECK_CAP(initCaps, caps, can_generate_monitor_events); 170 CHECK_CAP(initCaps, caps, can_generate_vm_object_alloc_events); 171 CHECK_CAP(initCaps, caps, can_generate_native_method_bind_events); 172 CHECK_CAP(initCaps, caps, can_generate_garbage_collection_events); 173 CHECK_CAP(initCaps, caps, can_generate_object_free_events); 174 /* :15 */ 175 /* :16 */ 176 /* :16 */ 177 /* :16 */ 178 /* :16 */ 179 /* :16 */ 180 181 return success; 182 } 183 184 /** 185 * Get and check current capabilities. 186 * @returns NSK_FALSE if any error occured. 187 */ 188 static int checkCapabilities(jvmtiEnv* jvmti, jvmtiCapabilities* initCaps, const char where[]) { 189 int success = NSK_TRUE; 190 jvmtiCapabilities caps; 191 192 memset(&caps, 0, sizeof(jvmtiCapabilities)); 193 194 NSK_DISPLAY0("GetCapabilities() for current JVMTI env\n"); 195 if (!NSK_JVMTI_VERIFY( 196 NSK_CPP_STUB2(GetCapabilities, jvmti, &caps))) { 197 return NSK_FALSE; 198 } 199 200 NSK_DISPLAY0("Got raw capabilities:\n"); 201 printRawCapabilities(&caps); 202 203 NSK_DISPLAY0("Known capabilities:\n"); 204 printKnownCapabilities(&caps); 205 206 NSK_DISPLAY0("Checking capabilities value:\n"); 207 success = checkCapabilitiesValue(&caps, initCaps, where); 208 NSK_DISPLAY0(" ... checked\n"); 209 210 return success; 211 } 212 213 /** 214 * Add given capabilities list. 215 * @returns NSK_FALSE if any error occured. 216 */ 217 static int addCapabilities(jvmtiEnv* jvmti, jvmtiCapabilities* caps, const char where[]) { 218 NSK_DISPLAY0("AddCapabilities() for current JVMTI env\n"); 219 if (!NSK_JVMTI_VERIFY( 220 NSK_CPP_STUB2(AddCapabilities, jvmti, caps))) { 221 return NSK_FALSE; 222 } 223 NSK_DISPLAY0(" ... set\n"); 224 225 return NSK_TRUE; 226 } 227 228 /* ============================================================================= */ 229 230 /** Agent algorithm. */ 231 static void JNICALL 232 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 233 NSK_DISPLAY0("Wait for debugee to become ready\n"); 234 if (!nsk_jvmti_waitForSync(timeout)) 235 return; 236 237 NSK_DISPLAY0(">>> Testcase #3: Check capabilities in agent thread\n"); 238 if (!checkCapabilities(jvmti, &initCaps, "agent thread")) { 239 nsk_jvmti_setFailStatus(); 240 } 241 242 NSK_DISPLAY0("Let debugee to finish\n"); 243 if (!nsk_jvmti_resumeSync()) 244 return; 245 } 246 247 /* ============================================================================= */ 248 249 /** 250 * Callback for VM_INIT event. 251 */ 252 JNIEXPORT void JNICALL 253 callbackVMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) { 254 255 NSK_DISPLAY0(">>> Testcase #2: Check capabilities in VM_INIT callback\n"); 256 if (!checkCapabilities(jvmti, &initCaps, "VM_INIT callback")) { 257 nsk_jvmti_setFailStatus(); 258 } 259 260 } 261 262 /** 263 * Callback for VM_DEATH event. 264 */ 265 JNIEXPORT void JNICALL 266 callbackVMDeath(jvmtiEnv* jvmti, JNIEnv* jni) { 267 int success = NSK_TRUE; 268 269 NSK_DISPLAY0(">>> Testcase #4: Check capabilities in VM_DEATH callback\n"); 270 success = checkCapabilities(jvmti, &initCaps, "VM_DEATH callback"); 271 272 NSK_DISPLAY1("Disable events: %d events\n", EVENTS_COUNT); 273 if (!nsk_jvmti_enableEvents(JVMTI_DISABLE, EVENTS_COUNT, events, NULL)) { 274 success = NSK_FALSE; 275 } else { 276 NSK_DISPLAY0(" ... disabled\n"); 277 } 278 279 if (!success) { 280 NSK_DISPLAY1("Exit with FAIL exit status: %d\n", STATUS_FAIL); 281 NSK_BEFORE_TRACE(exit(STATUS_FAIL)); 282 } 283 } 284 285 /* ============================================================================= */ 286 287 /** Agent library initialization. */ 288 #ifdef STATIC_BUILD 289 JNIEXPORT jint JNICALL Agent_OnLoad_addcaps001(JavaVM *jvm, char *options, void *reserved) { 290 return Agent_Initialize(jvm, options, reserved); 291 } 292 JNIEXPORT jint JNICALL Agent_OnAttach_addcaps001(JavaVM *jvm, char *options, void *reserved) { 293 return Agent_Initialize(jvm, options, reserved); 294 } 295 JNIEXPORT jint JNI_OnLoad_addcaps001(JavaVM *jvm, char *options, void *reserved) { 296 return JNI_VERSION_1_8; 297 } 298 #endif 299 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 300 jvmtiEnv* jvmti = NULL; 301 302 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 303 return JNI_ERR; 304 305 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 306 307 if (!NSK_VERIFY((jvmti = 308 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 309 return JNI_ERR; 310 311 { 312 jvmtiEventCallbacks eventCallbacks; 313 314 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 315 eventCallbacks.VMInit = callbackVMInit; 316 eventCallbacks.VMDeath = callbackVMDeath; 317 if (!NSK_JVMTI_VERIFY( 318 NSK_CPP_STUB3(SetEventCallbacks, jvmti, 319 &eventCallbacks, sizeof(eventCallbacks)))) { 320 return JNI_ERR; 321 } 322 323 } 324 325 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 326 return JNI_ERR; 327 328 NSK_DISPLAY0(">>> Testcase #0: Add empty capabilities list in Agent_OnLoad()\n"); 329 memset(&initCaps, 0, sizeof(jvmtiCapabilities)); 330 if (!addCapabilities(jvmti, &initCaps, "Agent_OnLoad()")) { 331 nsk_jvmti_setFailStatus(); 332 } 333 334 NSK_DISPLAY0(">>> Testcase #1: Check capabilities in Agent_OnLoad()\n"); 335 if (!checkCapabilities(jvmti, &initCaps, "Agent_OnLoad()")) { 336 nsk_jvmti_setFailStatus(); 337 } 338 339 NSK_DISPLAY1("Enable events: %d events\n", EVENTS_COUNT); 340 if (nsk_jvmti_enableEvents(JVMTI_ENABLE, EVENTS_COUNT, events, NULL)) { 341 NSK_DISPLAY0(" ... enabled\n"); 342 } 343 344 return JNI_OK; 345 } 346 347 /* ============================================================================= */ 348 349 }