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 <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <jvmti.h> 28 #include "agent_common.h" 29 30 #include "nsk_tools.h" 31 #include "jni_tools.h" 32 #include "JVMTITools.h" 33 #include "jvmti_tools.h" 34 35 extern "C" { 36 37 #define PASSED 0 38 #define STATUS_FAILED 2 39 40 #define EXP_OBJ_FREE 2 41 42 static JNIEnv *jni = NULL; 43 static jvmtiEnv *jvmti = NULL; 44 static jvmtiEventCallbacks callbacks; 45 static jvmtiCapabilities caps; 46 47 static volatile int obj_free = 0; 48 static volatile long obj_count = 0; 49 50 static jlong timeout = 0; 51 static int user_data = 0; 52 static const char* DEBUGEE_SIGNATURE = "Lnsk/jvmti/scenarios/allocation/AP12/ap12t001;"; 53 static const jlong DEBUGEE_CLASS_TAG = (jlong)1024; 54 55 void JNICALL 56 ObjectFree(jvmtiEnv *jvmti_env, jlong tag) { 57 NSK_DISPLAY1("ObjectFree event received for an object with tag %ld\n\n", (long)tag); 58 obj_free++; 59 } 60 61 void JNICALL 62 VMDeath(jvmtiEnv *jvmti_env, JNIEnv *env) { 63 64 NSK_DISPLAY0("VMDeath event received\n"); 65 66 if (obj_free != EXP_OBJ_FREE) { 67 NSK_COMPLAIN2( 68 "Received unexpected number of ObjectFree events: %d\n" 69 "\texpected number: %d\n", 70 obj_free, EXP_OBJ_FREE); 71 exit(95 + STATUS_FAILED); 72 } 73 74 exit(95 + PASSED); 75 } 76 77 /************************/ 78 79 JNIEXPORT void JNICALL 80 Java_nsk_jvmti_scenarios_allocation_AP12_ap12t001_setTag( JNIEnv* jni, jobject obj, jlong tag) { 81 82 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(obj, tag))) { 83 nsk_jvmti_setFailStatus(); 84 } 85 } 86 87 static void JNICALL 88 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 89 90 jclass debugeeClass = NULL; 91 92 NSK_DISPLAY0("Wait for debugee start\n\n"); 93 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) 94 return; 95 96 NSK_DISPLAY0("Let debugee to provoke GC\n"); 97 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) 98 return; 99 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) 100 return; 101 102 NSK_DISPLAY0("Let debugee to finish\n"); 103 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) 104 return; 105 } 106 107 #ifdef STATIC_BUILD 108 JNIEXPORT jint JNICALL Agent_OnLoad_ap12t001(JavaVM *jvm, char *options, void *reserved) { 109 return Agent_Initialize(jvm, options, reserved); 110 } 111 JNIEXPORT jint JNICALL Agent_OnAttach_ap12t001(JavaVM *jvm, char *options, void *reserved) { 112 return Agent_Initialize(jvm, options, reserved); 113 } 114 JNIEXPORT jint JNI_OnLoad_ap12t001(JavaVM *jvm, char *options, void *reserved) { 115 return JNI_VERSION_1_8; 116 } 117 #endif 118 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 119 /* init framework and parse options */ 120 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 121 return JNI_ERR; 122 123 /* create JVMTI environment */ 124 if (!NSK_VERIFY((jvmti = 125 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 126 return JNI_ERR; 127 128 memset(&caps, 0, sizeof(jvmtiCapabilities)); 129 caps.can_generate_object_free_events = 1; 130 caps.can_tag_objects = 1; 131 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 132 return JNI_ERR; 133 134 if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps))) 135 return JNI_ERR; 136 137 if (!caps.can_generate_object_free_events) 138 NSK_DISPLAY0("Warning: generation of object free events is not implemented\n"); 139 if (!caps.can_tag_objects) 140 NSK_DISPLAY0("Warning: tagging objects is not implemented\n"); 141 142 /* set event callback */ 143 NSK_DISPLAY0("setting event callbacks ...\n"); 144 (void) memset(&callbacks, 0, sizeof(callbacks)); 145 146 callbacks.ObjectFree = &ObjectFree; 147 callbacks.VMDeath = &VMDeath; 148 149 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)))) 150 return JNI_ERR; 151 152 NSK_DISPLAY0("setting event callbacks done\nenabling JVMTI events ...\n"); 153 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, 154 JVMTI_EVENT_OBJECT_FREE, 155 NULL))) 156 return JNI_ERR; 157 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, 158 JVMTI_EVENT_VM_DEATH, 159 NULL))) 160 return JNI_ERR; 161 NSK_DISPLAY0("enabling the events done\n\n"); 162 163 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 164 return JNI_ERR; 165 NSK_DISPLAY0("agentProc has been set\n\n"); 166 167 return JNI_OK; 168 } 169 170 }