1 /* 2 * Copyright (c) 2008, 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 #include <string.h> 24 #include <stdlib.h> 25 #include <jvmti_aod.h> 26 27 extern "C" { 28 29 void nsk_jvmti_aod_disableEventAndFinish(const char* agentName, jvmtiEvent event, int success, jvmtiEnv *jvmti, JNIEnv* jni) { 30 if (!nsk_jvmti_aod_disableEvent(jvmti, event)) 31 success = 0; 32 33 nsk_aod_agentFinished(jni, agentName, success); 34 } 35 36 void nsk_jvmti_aod_disableEventsAndFinish(const char* agentName, jvmtiEvent events[], int eventsNumber, int success, jvmtiEnv *jvmti, JNIEnv* jni) { 37 if (!nsk_jvmti_aod_disableEvents(jvmti, events, eventsNumber)) 38 success = 0; 39 40 nsk_aod_agentFinished(jni, agentName, success); 41 } 42 43 /* 44 * Work with agent options 45 */ 46 47 struct { 48 jvmtiEnv *jvmti; 49 Options *options; 50 } multiagentsOptions[MAX_MULTIPLE_AGENTS]; 51 52 static volatile int multiagentsCount = 0; 53 54 int nsk_jvmti_aod_addMultiagentsOptions(jvmtiEnv *jvmti, Options *options) { 55 if (multiagentsCount >= MAX_MULTIPLE_AGENTS) { 56 NSK_COMPLAIN1("To many agents, max agents count is %d\n", MAX_MULTIPLE_AGENTS); 57 return NSK_FALSE; 58 } 59 60 multiagentsOptions[multiagentsCount].jvmti = jvmti; 61 multiagentsOptions[multiagentsCount].options = options; 62 multiagentsCount++; 63 64 NSK_DISPLAY3("Options for agent %s were added (jvmtiEnv: %p, agentsCount: %d)\n", 65 nsk_aod_getOptionValue(options, NSK_AOD_AGENT_NAME_OPTION), 66 jvmti, 67 multiagentsCount); 68 69 return NSK_TRUE; 70 } 71 72 Options* nsk_jvmti_aod_getMultiagentsOptions(jvmtiEnv *jvmti) { 73 int i; 74 for (i = 0; i < multiagentsCount; i++) { 75 if (multiagentsOptions[i].jvmti == jvmti) { 76 return multiagentsOptions[i].options; 77 } 78 } 79 80 NSK_COMPLAIN1("Options for jvmtiEnv %p weren't found\n", jvmti); 81 82 return NULL; 83 } 84 85 /* 86 * Auxiliary functions 87 */ 88 89 void nsk_jvmti_aod_deallocate(jvmtiEnv *jvmti, unsigned char* mem) { 90 if (!NSK_JVMTI_VERIFY(jvmti->Deallocate(mem))) { 91 NSK_COMPLAIN0("Deallocate failed\n"); 92 93 /* 94 * if deallocate fails it isn't critical and test execution can continue without problems, 95 * just call nsk_aod_internal_error to inform framework about this error 96 */ 97 nsk_aod_internal_error(); 98 } 99 } 100 101 int nsk_jvmti_aod_getClassName(jvmtiEnv *jvmti, jclass klass, char classNameBuffer[]) { 102 char* className; 103 104 if (!NSK_JVMTI_VERIFY(jvmti->GetClassSignature(klass, &className, NULL))) { 105 NSK_COMPLAIN0("Failed to get class name\n"); 106 classNameBuffer[0] = '\0'; 107 return NSK_FALSE; 108 } else { 109 strcpy(classNameBuffer, className); 110 111 nsk_jvmti_aod_deallocate(jvmti, (unsigned char*)className); 112 113 return NSK_TRUE; 114 } 115 } 116 117 int nsk_jvmti_aod_getThreadName(jvmtiEnv * jvmti, jthread thread, char threadNameBuffer[]) { 118 jvmtiThreadInfo info; 119 if (!NSK_JVMTI_VERIFY(jvmti->GetThreadInfo(thread, &info))){ 120 NSK_COMPLAIN0("Failed to get thread info\n"); 121 threadNameBuffer[0] = '\0'; 122 return NSK_FALSE; 123 } else { 124 strcpy(threadNameBuffer, info.name); 125 126 nsk_jvmti_aod_deallocate(jvmti, (unsigned char*)info.name); 127 128 return NSK_TRUE; 129 } 130 } 131 132 // events enabling/disabling 133 134 int nsk_jvmti_aod_disableEvents(jvmtiEnv* jvmti, jvmtiEvent events[], int eventsNumber) { 135 int i; 136 int status = NSK_TRUE; 137 138 for (i = 0; i < eventsNumber; i++) { 139 if (!nsk_jvmti_aod_disableEvent(jvmti, events[i])) { 140 status = NSK_FALSE; 141 } 142 } 143 144 return status; 145 } 146 147 int nsk_jvmti_aod_enableEvents(jvmtiEnv* jvmti, jvmtiEvent events[], int eventsNumber) { 148 int i; 149 for (i = 0; i < eventsNumber; i++) { 150 if (!nsk_jvmti_aod_enableEvent(jvmti, events[i])) 151 return NSK_FALSE; 152 } 153 154 return NSK_TRUE; 155 } 156 157 // java threads creation 158 159 jthread nsk_jvmti_aod_createThread(JNIEnv *jni) { 160 jclass klass ; 161 jmethodID threadConstructor; 162 jthread thread; 163 164 if (!NSK_JNI_VERIFY(jni, (klass = jni->FindClass("java/lang/Thread")) != NULL )) { 165 NSK_COMPLAIN0("Failed to get the java.lang.Thread class\n"); 166 return NULL; 167 } 168 if (!NSK_JNI_VERIFY(jni, 169 (threadConstructor = jni->GetMethodID(klass, "<init>", "()V") ) != NULL )) { 170 NSK_COMPLAIN0("Failed to get java.lang.Thread constructor\n"); 171 return NULL; 172 } 173 174 if (!NSK_JNI_VERIFY (jni, 175 (thread = jni->NewObject(klass, threadConstructor, NULL)) != NULL ) ) { 176 NSK_COMPLAIN0("Failed to create Thread object\n"); 177 return NULL; 178 } 179 180 if (!NSK_JNI_VERIFY(jni, (thread = jni->NewGlobalRef(thread)) != NULL)) { 181 NSK_COMPLAIN0("Failed to create global reference\n"); 182 return NULL; 183 } 184 185 return thread; 186 } 187 188 jthread nsk_jvmti_aod_createThreadWithName(JNIEnv *jni, const char* threadName) { 189 jclass klass ; 190 jmethodID threadConstructor; 191 jthread thread; 192 jstring threadNameString; 193 194 if (!NSK_JNI_VERIFY(jni, (threadNameString = jni->NewStringUTF(threadName)) != NULL)) 195 return NULL; 196 197 if (!NSK_JNI_VERIFY(jni, (klass = jni->FindClass("java/lang/Thread")) != NULL )) { 198 NSK_COMPLAIN0("Failed to get the java.lang.Thread class\n"); 199 return NULL; 200 } 201 if (!NSK_JNI_VERIFY(jni, 202 (threadConstructor = jni->GetMethodID(klass, "<init>", "(Ljava/lang/String;)V") ) != NULL )) { 203 NSK_COMPLAIN0("Failed to get java.lang.Thread constructor\n"); 204 return NULL; 205 } 206 207 if (!NSK_JNI_VERIFY(jni, 208 (thread = jni->NewObject(klass, threadConstructor, threadNameString)) != NULL ) ) { 209 NSK_COMPLAIN0("Failed to create Thread object\n"); 210 return NULL; 211 } 212 213 if (!NSK_JNI_VERIFY(jni, (thread = jni->NewGlobalRef(thread)) != NULL)) { 214 NSK_COMPLAIN0("Failed to create global reference\n"); 215 return NULL; 216 } 217 218 return thread; 219 } 220 221 // class redefinition 222 223 int nsk_jvmti_aod_redefineClass( 224 Options * options, 225 jvmtiEnv * jvmti, 226 jclass classToRedefine, 227 const char * fileName) { 228 229 if (!nsk_aod_optionSpecified(options, PATH_TO_NEW_BYTE_CODE_OPTION)) { 230 NSK_COMPLAIN1("Option '%s' isn't specified\n", PATH_TO_NEW_BYTE_CODE_OPTION); 231 return NSK_FALSE; 232 } 233 if (fileName == NULL) { 234 NSK_COMPLAIN0("File name is NULL\n"); 235 return NSK_FALSE; 236 } 237 { 238 char file [1024]; 239 240 sprintf(file,"%s/%s.class", 241 nsk_aod_getOptionValue(options, PATH_TO_NEW_BYTE_CODE_OPTION), 242 fileName); 243 NSK_DISPLAY1("File with new bytecode: '%s'\n", file); 244 245 { 246 FILE *bytecode; 247 unsigned char * classBytes; 248 jvmtiError error; 249 jint size; 250 251 bytecode = fopen(file, "rb"); 252 error= JVMTI_ERROR_NONE; 253 if ( bytecode == NULL ) { 254 NSK_COMPLAIN1("Error opening file '%s'\n", file); 255 return NSK_FALSE; 256 } 257 258 NSK_DISPLAY1("Opening file '%s' \n", file); 259 fseek(bytecode, 0, SEEK_END); 260 size = ftell(bytecode); 261 NSK_DISPLAY1("File size= %ld\n", ftell(bytecode)); 262 rewind(bytecode); 263 error = jvmti->Allocate(size, &classBytes); 264 if ( error != JVMTI_ERROR_NONE) { 265 NSK_DISPLAY1("Failed to create memory %s\n", TranslateError(error)); 266 return NSK_FALSE; 267 } 268 269 if ( ((jint) fread( classBytes, 1, size, bytecode )) != size ) { 270 NSK_COMPLAIN0("Failed to read all the bytes, could be less or more\n"); 271 fclose(bytecode); 272 return NSK_FALSE; 273 } else { 274 NSK_DISPLAY0("File read completely \n"); 275 } 276 fclose(bytecode); 277 { 278 jvmtiClassDefinition classDef; 279 classDef.klass = classToRedefine; 280 classDef.class_byte_count= size; 281 classDef.class_bytes = classBytes; 282 NSK_DISPLAY0("Redefining\n"); 283 error = jvmti->RedefineClasses(1, &classDef); 284 if ( error != JVMTI_ERROR_NONE ) { 285 NSK_DISPLAY1("# error occured while redefining %s ", 286 TranslateError(error) ); 287 return NSK_FALSE; 288 } 289 } 290 } 291 } 292 return NSK_TRUE; 293 } 294 295 // capabilities 296 297 void printCapabilities(jvmtiCapabilities caps) { 298 #define printCap(name) NSK_DISPLAY1(#name ": %d\n", caps.name) 299 300 printCap(can_tag_objects); 301 printCap(can_generate_field_modification_events); 302 printCap(can_generate_field_access_events); 303 printCap(can_get_bytecodes); 304 printCap(can_get_synthetic_attribute); 305 printCap(can_get_owned_monitor_info); 306 printCap(can_get_current_contended_monitor); 307 printCap(can_get_monitor_info); 308 printCap(can_pop_frame); 309 printCap(can_redefine_classes); 310 printCap(can_signal_thread); 311 printCap(can_get_source_file_name); 312 printCap(can_get_line_numbers); 313 printCap(can_get_source_debug_extension); 314 printCap(can_access_local_variables); 315 printCap(can_maintain_original_method_order); 316 printCap(can_generate_single_step_events); 317 printCap(can_generate_exception_events); 318 printCap(can_generate_frame_pop_events); 319 printCap(can_generate_breakpoint_events); 320 printCap(can_suspend); 321 printCap(can_redefine_any_class); 322 printCap(can_get_current_thread_cpu_time); 323 printCap(can_get_thread_cpu_time); 324 printCap(can_generate_method_entry_events); 325 printCap(can_generate_method_exit_events); 326 printCap(can_generate_all_class_hook_events); 327 printCap(can_generate_compiled_method_load_events); 328 printCap(can_generate_monitor_events); 329 printCap(can_generate_vm_object_alloc_events); 330 printCap(can_generate_native_method_bind_events); 331 printCap(can_generate_garbage_collection_events); 332 printCap(can_generate_object_free_events); 333 printCap(can_force_early_return); 334 printCap(can_get_owned_monitor_stack_depth_info); 335 printCap(can_get_constant_pool); 336 printCap(can_set_native_method_prefix); 337 printCap(can_retransform_classes); 338 printCap(can_retransform_any_class); 339 340 #undef printCap 341 } 342 343 }