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 <stdio.h> 25 #include <string.h> 26 #include "jvmti.h" 27 #include "agent_common.h" 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #ifndef JNI_ENV_ARG 34 35 #ifdef __cplusplus 36 #define JNI_ENV_ARG(x, y) y 37 #define JNI_ENV_ARG1(x) 38 #define JNI_ENV_PTR(x) x 39 #else 40 #define JNI_ENV_ARG(x,y) x, y 41 #define JNI_ENV_ARG1(x) x 42 #define JNI_ENV_PTR(x) (*x) 43 #endif 44 45 #endif 46 47 #define JVMTI_ENV_ARG JNI_ENV_ARG 48 #define JVMTI_ENV_ARG1 JNI_ENV_ARG1 49 #define JVMTI_ENV_PTR JNI_ENV_PTR 50 51 #define JVMTI_ERROR_CHECK(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;} 52 #define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if ( res != err) { printf(str); printf("unexpected error %d\n",res); return res;} 53 54 #define JVMTI_ERROR_CHECK_VOID(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; } 55 56 #define JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID(str,res,err) if ( res != err) { printf(str); printf("unexpected error %d\n",res); iGlobalStatus = 2; } 57 58 #define THREADS_LIMIT 2000 59 60 61 jvmtiEnv *jvmti; 62 jint iGlobalStatus = 0; 63 jthread susp_thrd[THREADS_LIMIT]; 64 static jvmtiEventCallbacks callbacks; 65 static jvmtiCapabilities jvmti_caps; 66 jrawMonitorID jraw_monitor[20]; 67 68 int process_once = 0; 69 70 71 72 int printdump = 0; 73 74 75 void debug_printf(const char *fmt, ...) { 76 va_list args; 77 78 va_start(args, fmt); 79 if (printdump) { 80 vprintf(fmt, args); 81 } 82 va_end(args); 83 } 84 85 86 void JNICALL vmInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) { 87 88 debug_printf("VMInit event done\n"); 89 90 } 91 92 void JNICALL vmExit(jvmtiEnv *jvmti_env, JNIEnv *env) { 93 debug_printf("------------ JVMTI_EVENT_VM_DEATH ------------\n"); 94 } 95 96 void JNICALL classFileLoadEvent(jvmtiEnv *jvmti_env, JNIEnv *env, 97 jclass class_being_redifined, 98 jobject loader, const char* name, 99 jobject protection_domain, 100 jint class_data_len, 101 const unsigned char* class_data, 102 jint* new_class_data_len, 103 unsigned char** new_class_data) { 104 105 } 106 107 108 109 void init_callbacks() { 110 memset((void *)&callbacks, 0, sizeof(jvmtiEventCallbacks)); 111 callbacks.VMInit = vmInit; 112 callbacks.VMDeath = vmExit; 113 callbacks.ClassFileLoadHook = classFileLoadEvent; 114 } 115 116 117 #ifdef STATIC_BUILD 118 JNIEXPORT jint JNICALL Agent_OnLoad_JvmtiTest(JavaVM *jvm, char *options, void *reserved) { 119 return Agent_Initialize(jvm, options, reserved); 120 } 121 JNIEXPORT jint JNICALL Agent_OnAttach_JvmtiTest(JavaVM *jvm, char *options, void *reserved) { 122 return Agent_Initialize(jvm, options, reserved); 123 } 124 JNIEXPORT jint JNI_OnLoad_JvmtiTest(JavaVM *jvm, char *options, void *reserved) { 125 return JNI_VERSION_1_8; 126 } 127 #endif 128 jint Agent_Initialize(JavaVM * jvm, char *options, void *reserved) { 129 jint res; 130 131 if (options && strlen(options) > 0) { 132 if (strstr(options, "printdump")) { 133 printdump = 1; 134 } 135 } 136 137 res = JNI_ENV_PTR(jvm)-> 138 GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), JVMTI_VERSION_1_1); 139 if (res < 0) { 140 debug_printf("Wrong result of a valid call to GetEnv!\n"); 141 return JNI_ERR; 142 } 143 144 145 /* Add capabilities */ 146 res = JVMTI_ENV_PTR(jvmti)->GetPotentialCapabilities(JVMTI_ENV_ARG(jvmti, &jvmti_caps)); 147 JVMTI_ERROR_CHECK("GetPotentialCapabilities returned error", res); 148 149 res = JVMTI_ENV_PTR(jvmti)->AddCapabilities(JVMTI_ENV_ARG(jvmti, &jvmti_caps)); 150 JVMTI_ERROR_CHECK("GetPotentialCapabilities returned error", res); 151 152 /* Enable events */ 153 init_callbacks(); 154 res = JVMTI_ENV_PTR(jvmti)->SetEventCallbacks(JVMTI_ENV_ARG(jvmti, &callbacks), sizeof(callbacks)); 155 JVMTI_ERROR_CHECK("SetEventCallbacks returned error", res); 156 157 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_VM_INIT,NULL); 158 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_INIT returned error", res); 159 160 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_VM_DEATH,NULL); 161 JVMTI_ERROR_CHECK("SetEventNotificationMode for vm death event returned error", res); 162 163 return JNI_OK; 164 } 165 166 167 JNIEXPORT jint JNICALL 168 Java_nsk_jvmti_unit_functions_nosuspendMonitorInfo_JvmtiTest_GetResult(JNIEnv * env, jclass cls) { 169 return iGlobalStatus; 170 } 171 172 JNIEXPORT void JNICALL 173 Java_nsk_jvmti_unit_functions_nosuspendMonitorInfo_JvmtiTest_CheckMonitorInfo(JNIEnv * env, jclass cls, jthread thr, jobject oobj, jint expected_count) { 174 175 jvmtiError ret; 176 jint count; 177 jobject *owned_monitor; 178 179 debug_printf(" jvmti GetMonitorInfo \n"); 180 181 182 ret = JVMTI_ENV_PTR(jvmti)->GetOwnedMonitorInfo(JVMTI_ENV_ARG(jvmti, thr), &count , &owned_monitor); 183 if (ret != JVMTI_ERROR_NONE) { 184 printf("Error: GetMonitorInfo %d \n", ret); 185 iGlobalStatus = 2; 186 } 187 188 if (expected_count != 0 && expected_count != count) { 189 printf("Error: GetMonitorInfo expected count %d but got %d \n", expected_count, count); 190 iGlobalStatus = 2; 191 } 192 193 if (expected_count !=0 ) { 194 195 ret = JVMTI_ENV_PTR(jvmti)->GetCurrentContendedMonitor(JVMTI_ENV_ARG(jvmti, thr), owned_monitor); 196 if (ret != JVMTI_ERROR_NONE) { 197 printf("Error: GetContendedMonitorInfo %d \n", ret); 198 iGlobalStatus = 2; 199 } 200 } 201 202 } 203 204 #ifdef __cplusplus 205 } 206 #endif