1 /* 2 * Copyright (c) 2007, 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 #include "JVMTITools.h" 29 30 extern "C" { 31 32 33 #define PASSED 0 34 #define STATUS_FAILED 2 35 36 static jvmtiCapabilities caps; 37 static jvmtiEventCallbacks callbacks; 38 39 #define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return 40 41 static jint errCode = PASSED; 42 static jvmtiEnv *jvmti = NULL; 43 static jmethodID midCheckPoint = NULL; 44 45 46 JNIEXPORT void JNICALL 47 Java_nsk_jvmti_unit_GetConstantPool_getcpool001_getCP( 48 JNIEnv *env, jclass c, jint id, jclass cls) { 49 jvmtiError err; 50 int idx = 0; 51 int rep = 0; 52 jint cp_cnt = 0; 53 jint cp_bytes_cnt = 0; 54 unsigned char *cp_bytes = NULL; 55 56 err = jvmti->GetConstantPool(cls, &cp_cnt, &cp_bytes_cnt, &cp_bytes); 57 if (err != JVMTI_ERROR_NONE) { 58 printf("(GetConstantPool) unexpected error: %s (%d)\n", 59 TranslateError(err), err); 60 RETURN_FAILED; 61 } 62 63 /* Print Constant Pool attrs*/ 64 printf("getCP: id = %d, cnt = %03d, bytes_cnt = %04d\n", 65 id, cp_cnt, cp_bytes_cnt); 66 fflush(0); 67 } 68 69 void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, 70 jthread thread, jmethodID method, jlocation location) { 71 jvmtiError err; 72 73 if (midCheckPoint != method) { 74 printf("bp: don't know where we get called from"); 75 RETURN_FAILED; 76 } 77 78 printf(">>> breakpoint in checkPoint\n"); 79 80 err = jvmti_env->ClearBreakpoint(midCheckPoint, 0); 81 if (err != JVMTI_ERROR_NONE) { 82 printf("(ClearBreakpoint) unexpected error: %s (%d)\n", 83 TranslateError(err), err); 84 RETURN_FAILED; 85 } 86 fflush(0); 87 } 88 89 #ifdef STATIC_BUILD 90 JNIEXPORT jint JNICALL Agent_OnLoad_getcpool001(JavaVM *jvm, char *options, void *reserved) { 91 return Agent_Initialize(jvm, options, reserved); 92 } 93 JNIEXPORT jint JNICALL Agent_OnAttach_getcpool001(JavaVM *jvm, char *options, void *reserved) { 94 return Agent_Initialize(jvm, options, reserved); 95 } 96 JNIEXPORT jint JNI_OnLoad_getcpool001(JavaVM *jvm, char *options, void *reserved) { 97 return JNI_VERSION_1_8; 98 } 99 #endif 100 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 101 jvmtiError err; 102 jint res; 103 104 res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1); 105 if (res != JNI_OK || jvmti == NULL) { 106 printf("Wrong result of a valid call to GetEnv!\n"); 107 return JNI_ERR; 108 } 109 110 err = jvmti->GetPotentialCapabilities(&caps); 111 if (err != JVMTI_ERROR_NONE) { 112 printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n", 113 TranslateError(err), err); 114 return JNI_ERR; 115 } 116 117 err = jvmti->AddCapabilities(&caps); 118 if (err != JVMTI_ERROR_NONE) { 119 printf("(AddCapabilities) unexpected error: %s (%d)\n", 120 TranslateError(err), err); 121 return JNI_ERR; 122 } 123 124 err = jvmti->GetCapabilities(&caps); 125 if (err != JVMTI_ERROR_NONE) { 126 printf("(GetCapabilities) unexpected error: %s (%d)\n", 127 TranslateError(err), err); 128 return JNI_ERR; 129 } 130 131 if (!caps.can_force_early_return) { 132 printf("Warning: GetConstantPool is not implemented\n"); 133 } 134 135 if (caps.can_generate_breakpoint_events && 136 caps.can_generate_single_step_events) { 137 callbacks.Breakpoint = &Breakpoint; 138 err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); 139 if (err != JVMTI_ERROR_NONE) { 140 printf("(SetEventCallbacks) unexpected error: %s (%d)\n", 141 TranslateError(err), err); 142 return JNI_ERR; 143 } 144 } 145 146 return JNI_OK; 147 } 148 149 JNIEXPORT void JNICALL 150 Java_nsk_jvmti_unit_GetConstantPool_getcpool001_getReady( 151 JNIEnv *env, jclass c, jclass cls) { 152 jvmtiError err; 153 154 if (jvmti == NULL) { 155 printf("JVMTI client was not properly loaded!\n"); 156 RETURN_FAILED; 157 } 158 159 if (!caps.can_force_early_return || 160 !caps.can_generate_breakpoint_events || 161 !caps.can_generate_single_step_events) { 162 return; 163 } 164 165 midCheckPoint = env->GetMethodID(cls, "checkPoint", "()V"); 166 if (midCheckPoint == NULL) { 167 printf("Cannot find Method ID for method checkPoint\n"); 168 RETURN_FAILED; 169 } 170 171 err = jvmti->SetBreakpoint(midCheckPoint, 0); 172 if (err != JVMTI_ERROR_NONE) { 173 printf("(SetBreakpoint) unexpected error: %s (%d)\n", 174 TranslateError(err), err); 175 RETURN_FAILED; 176 } 177 178 err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL); 179 if (err != JVMTI_ERROR_NONE) { 180 printf("Failed to enable BREAKPOINT event: %s (%d)\n", 181 TranslateError(err), err); 182 RETURN_FAILED; 183 } 184 185 } 186 187 JNIEXPORT jint JNICALL 188 Java_nsk_jvmti_unit_GetConstantPool_getcpool001_check(JNIEnv *env, jclass cls) { 189 return errCode; 190 } 191 192 }