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