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_nosuspendStackTrace_JvmtiTest_GetResult(JNIEnv * env, jclass cls) { 169 return iGlobalStatus; 170 } 171 172 173 JNIEXPORT void JNICALL 174 Java_nsk_jvmti_unit_functions_nosuspendStackTrace_JvmtiTest_CreateRawMonitor(JNIEnv * env, jclass cls, jint i) { 175 jvmtiError ret; 176 char sz[128]; 177 178 sprintf(sz, "Rawmonitor-%d",i); 179 debug_printf("jvmti create raw monitor \n"); 180 ret = JVMTI_ENV_PTR(jvmti)->CreateRawMonitor(JVMTI_ENV_ARG(jvmti, sz), &jraw_monitor[i]); 181 182 if (ret != JVMTI_ERROR_NONE) { 183 printf("Error: ForceGarbageCollection %d \n", ret); 184 iGlobalStatus = 2; 185 } 186 } 187 188 JNIEXPORT void JNICALL 189 Java_nsk_jvmti_unit_functions_nosuspendStackTrace_JvmtiTest_RawMonitorEnter(JNIEnv * env, jclass cls, jint i) { 190 jvmtiError ret; 191 192 debug_printf("jvmti Raw monitor enter \n"); 193 ret = JVMTI_ENV_PTR(jvmti)->RawMonitorEnter(JVMTI_ENV_ARG(jvmti, jraw_monitor[i])); 194 195 if (ret != JVMTI_ERROR_NONE) { 196 printf("Error: Raw monitor enter %d \n", ret); 197 iGlobalStatus = 2; 198 } 199 } 200 201 JNIEXPORT void JNICALL 202 Java_nsk_jvmti_unit_functions_nosuspendStackTrace_JvmtiTest_RawMonitorExit(JNIEnv * env, jclass cls, jint i) { 203 jvmtiError ret; 204 205 debug_printf("jvmti raw monitor exit \n"); 206 ret = JVMTI_ENV_PTR(jvmti)->RawMonitorExit(JVMTI_ENV_ARG(jvmti, jraw_monitor[i])); 207 208 if (ret != JVMTI_ERROR_NONE) { 209 printf("Error: RawMonitorExit %d \n", ret); 210 iGlobalStatus = 2; 211 } 212 } 213 214 JNIEXPORT void JNICALL 215 Java_nsk_jvmti_unit_functions_nosuspendStackTrace_JvmtiTest_RawMonitorWait(JNIEnv * env, jclass cls, jint i) { 216 jvmtiError ret; 217 218 debug_printf("jvmti RawMonitorWait \n"); 219 ret = JVMTI_ENV_PTR(jvmti)->RawMonitorWait(JVMTI_ENV_ARG(jvmti,jraw_monitor[i]),-1); 220 221 if (ret != JVMTI_ERROR_NONE) { 222 printf("Error: RawMonitorWait %d \n", ret); 223 iGlobalStatus = 2; 224 } 225 } 226 227 JNIEXPORT void JNICALL 228 Java_nsk_jvmti_unit_functions_nosuspendStackTrace_JvmtiTest_RawMonitorNotify(JNIEnv * env, jclass cls, jint i) { 229 jvmtiError ret; 230 231 debug_printf("jvmti RawMonitorNotify \n"); 232 ret = JVMTI_ENV_PTR(jvmti)->RawMonitorNotifyAll(JVMTI_ENV_ARG(jvmti,jraw_monitor[i])); 233 234 if (ret != JVMTI_ERROR_NONE) { 235 printf("Error: RawMonitorNotify %d \n", ret); 236 iGlobalStatus = 2; 237 } 238 } 239 240 JNIEXPORT int JNICALL 241 Java_nsk_jvmti_unit_functions_nosuspendStackTrace_JvmtiTest_GetFrameCount(JNIEnv * env, jclass cls, jobject thr) { 242 jvmtiError ret; 243 jint count; 244 245 debug_printf("jvmti GetFrameCount \n"); 246 ret = JVMTI_ENV_PTR(jvmti)->GetFrameCount(JVMTI_ENV_ARG(jvmti, (jthread)thr), &count); 247 if (ret != JVMTI_ERROR_NONE) { 248 printf("Error: GetFrameCount returned %d \n", ret); 249 iGlobalStatus = 2; 250 } 251 return count; 252 } 253 254 JNIEXPORT void JNICALL 255 Java_nsk_jvmti_unit_functions_nosuspendStackTrace_JvmtiTest_GetStackTrace(JNIEnv * env, jclass cls, jobject thr) { 256 jvmtiError ret; 257 jvmtiFrameInfo *stack_buffer = NULL; 258 jint count = 20; 259 jclass klass; 260 char *mname; 261 char *signature; 262 char *clname; 263 char *generic; 264 int i; 265 266 267 debug_printf("jvmti GetStackTrace \n"); 268 269 ret = JVMTI_ENV_PTR(jvmti)->Allocate(JVMTI_ENV_ARG(jvmti, sizeof(jvmtiFrameInfo) * count), (unsigned char**)&stack_buffer); 270 if (ret != JVMTI_ERROR_NONE) { 271 printf("Error: Allocate failed with %d \n", ret); 272 iGlobalStatus = 2; 273 } 274 275 276 ret = JVMTI_ENV_PTR(jvmti)->GetStackTrace(JVMTI_ENV_ARG(jvmti, thr), 0, count , stack_buffer, &count); 277 278 if (ret != JVMTI_ERROR_NONE) { 279 printf("Error: GetStackTrace %d \n", ret); 280 iGlobalStatus = 2; 281 } 282 283 debug_printf(" Java Stack trace ---\n"); 284 285 for (i = 0; i < count; i++) { 286 ret = JVMTI_ENV_PTR(jvmti)->GetMethodDeclaringClass(JVMTI_ENV_ARG(jvmti, stack_buffer[i].method), &klass); 287 if (ret != JVMTI_ERROR_NONE) { 288 printf("Error: GetMethodDeclaringClass %d \n", ret); 289 iGlobalStatus = 2; 290 return; 291 } 292 293 ret = JVMTI_ENV_PTR(jvmti)->GetClassSignature(JVMTI_ENV_ARG(jvmti, klass), &clname, &generic); 294 if (ret != JVMTI_ERROR_NONE) { 295 printf("Error: GetMethodDeclaringClass %d \n", ret); 296 iGlobalStatus = 2; 297 return; 298 } 299 300 ret = JVMTI_ENV_PTR(jvmti)->GetMethodName(JVMTI_ENV_ARG(jvmti, stack_buffer[i].method), &mname, &signature, &generic); 301 if (ret != JVMTI_ERROR_NONE) { 302 printf("Error: GetMethodDeclaringClass %d \n", ret); 303 iGlobalStatus = 2; 304 return; 305 } 306 307 debug_printf("[%d] %s::%s(%s) at %lld \n",i,clname, mname, signature, stack_buffer[i].location); 308 309 310 } 311 312 313 ret = JVMTI_ENV_PTR(jvmti)->Deallocate(JVMTI_ENV_ARG(jvmti, (unsigned char *)stack_buffer)); 314 if (ret != JVMTI_ERROR_NONE) { 315 printf("Error: Deallocate failed with %d \n", ret); 316 iGlobalStatus = 2; 317 } 318 319 320 } 321 322 JNIEXPORT void JNICALL 323 Java_nsk_jvmti_unit_functions_nosuspendStackTrace_JvmtiTest_SaveThreadInfo(JNIEnv * env, jclass cls, jobject oobj) { 324 325 } 326 327 #ifdef __cplusplus 328 } 329 #endif