blob: 6dc5f27a170a0ddf6fe07bd9dc03bff86272cc48 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Valentin Al. Sitnick
*
*/
#include "utils.h"
typedef struct
{
jvmtiError code;
const char* text;
} jvmti_error_text;
static jvmti_error_text jvmti_errors[] =
{
{JVMTI_ERROR_NONE, "JVMTI_ERROR_NONE"},
{JVMTI_ERROR_NULL_POINTER, "JVMTI_ERROR_NULL_POINTER"},
{JVMTI_ERROR_OUT_OF_MEMORY, "JVMTI_ERROR_OUT_OF_MEMORY"},
{JVMTI_ERROR_ACCESS_DENIED, "JVMTI_ERROR_ACCESS_DENIED"},
{JVMTI_ERROR_UNATTACHED_THREAD, "JVMTI_ERROR_UNATTACHED_THREAD"},
{JVMTI_ERROR_INVALID_ENVIRONMENT, "JVMTI_ERROR_INVALID_ENVIRONMENT"},
{JVMTI_ERROR_WRONG_PHASE, "JVMTI_ERROR_WRONG_PHASE"},
{JVMTI_ERROR_INTERNAL, "JVMTI_ERROR_INTERNAL"},
{JVMTI_ERROR_NOT_AVAILABLE, "JVMTI_ERROR_NOT_AVAILABLE"},
{JVMTI_ERROR_MUST_POSSESS_CAPABILITY, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY"},
};
const char* get_jvmti_eror_text(jvmtiError code)
{
for (unsigned int i = 0; i < sizeof(jvmti_errors) / sizeof(jvmti_errors[0]); i++)
{
if (jvmti_errors[i].code == code)
return jvmti_errors[i].text;
}
return "Unknown jvmti error";
}
/* *********************************************************************** */
/*
* Function for outputting names of current states of thread as a string.
*/
void thread_state_output_as_string(long state)
{
bool pipe = false;
if (state & JVMTI_THREAD_STATE_ALIVE )
{
fprintf(stderr, " _ALIVE ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_TERMINATED )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _TERMINATED ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_RUNNABLE )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _RUNNABLE ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _BLOCKED_ON_MONITOR_ENTER ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_WAITING )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _WAITING ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_WAITING_INDEFINITELY )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _WAITING_INDEFINITELY ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _WAITING_WITH_TIMEOUT ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_SLEEPING )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _SLEEPING ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_IN_OBJECT_WAIT )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _IN_OBJECT_WAIT ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_PARKED )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _PARKED ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_SUSPENDED )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _SUSPENDED ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_INTERRUPTED )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _INTERRUPTED ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_IN_NATIVE )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _IN_NATIVE ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_VENDOR_1 )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _VENDOR_1 ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_VENDOR_2 )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _VENDOR_2 ");
pipe = true;
}
if (state & JVMTI_THREAD_STATE_VENDOR_3 )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _VENDOR_3 ");
pipe = true;
}
return;
}
/*
* Function for outputting names of current statuses of class as a string.
*/
void class_status_output_as_string(long status)
{
bool pipe = false;
if ( status & JVMTI_CLASS_STATUS_VERIFIED )
{
fprintf(stderr, " _VERIFIED ");
pipe = true;
}
if ( status & JVMTI_CLASS_STATUS_PREPARED )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _PREPARED ");
pipe = true;
}
if ( status & JVMTI_CLASS_STATUS_INITIALIZED )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _INITIALIZED ");
pipe = true;
}
if ( status & JVMTI_CLASS_STATUS_ERROR )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _ERROR ");
pipe = true;
}
if ( status & JVMTI_CLASS_STATUS_ARRAY )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _ARRAY ");
pipe = true;
}
if ( status & JVMTI_CLASS_STATUS_PRIMITIVE )
{
if (pipe) fprintf(stderr, "|");
fprintf(stderr, " _PRIMITIVE ");
pipe = true;
}
return;
}
/*
* Function for comparing of 2 capabilities structure and output result
* of this operation.
*/
int cmp_caps_and_output_results(jvmtiCapabilities c1,
jvmtiCapabilities c2, const char* name1, const char* name2)
{
int diff = 0;
if (c1.can_tag_objects
!= c2.can_tag_objects)
{
fprintf(stderr, "\t\tDIFF: can_tag_objects %d in %s and %d in %s\n",
c1.can_tag_objects, name1, c2.can_tag_objects, name2);
diff++;
}
if (c1.can_generate_field_modification_events
!= c2.can_generate_field_modification_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_field_modification_events %d in %s and %d in %s\n",
c1.can_generate_field_modification_events, name1, c2.can_generate_field_modification_events, name2);
diff++;
}
if (c1.can_generate_field_access_events
!= c2.can_generate_field_access_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_field_access_events %d in %s and %d in %s\n",
c1.can_generate_field_access_events, name1, c2.can_generate_field_access_events, name2);
diff++;
}
if (c1.can_get_bytecodes
!= c2.can_get_bytecodes)
{
fprintf(stderr, "\t\tDIFF: can_get_bytecodes %d in %s and %d in %s\n",
c1.can_get_bytecodes, name1, c2.can_get_bytecodes, name2);
diff++;
}
if (c1.can_get_synthetic_attribute
!= c2.can_get_synthetic_attribute)
{
fprintf(stderr, "\t\tDIFF: can_get_synthetic_attribute in %d in %s and %d in %s\n",
c1.can_get_synthetic_attribute, name1, c2.can_get_synthetic_attribute, name2);
diff++;
}
if (c1.can_get_owned_monitor_info
!= c2.can_get_owned_monitor_info)
{
fprintf(stderr, "\t\tDIFF: can_get_owned_monitor_info in %d in %s and %d in %s\n",
c1.can_get_owned_monitor_info, name1, c2.can_get_owned_monitor_info, name2);
diff++;
}
if (c1.can_get_current_contended_monitor
!= c2.can_get_current_contended_monitor)
{
fprintf(stderr, "\t\tDIFF: can_get_current_contended_monitor %d in %s and %d in %s\n",
c1.can_get_current_contended_monitor, name1, c2.can_get_current_contended_monitor, name2);
diff++;
}
if (c1.can_get_monitor_info
!= c2.can_get_monitor_info)
{
fprintf(stderr, "\t\tDIFF: can_get_monitor_info %d in %s and %d in %s\n",
c1.can_get_monitor_info, name1, c2.can_get_monitor_info, name2);
diff++;
}
if (c1.can_pop_frame
!= c2.can_pop_frame)
{
fprintf(stderr, "\t\tDIFF: can_pop_frame %d in %s and %d in %s\n",
c1.can_pop_frame, name1, c2.can_pop_frame, name2);
diff++;
}
if (c1.can_redefine_classes
!= c2.can_redefine_classes)
{
fprintf(stderr, "\t\tDIFF: can_redefine_classes %d in %s and %d in %s\n",
c1.can_redefine_classes, name1, c2.can_redefine_classes, name2);
diff++;
}
if (c1.can_signal_thread
!= c2.can_signal_thread)
{
fprintf(stderr, "\t\tDIFF: can_signal_thread %d in %s and %d in %s\n",
c1.can_signal_thread, name1, c2.can_signal_thread, name2);
diff++;
}
if (c1.can_get_source_file_name
!= c2.can_get_source_file_name)
{
fprintf(stderr, "\t\tDIFF: can_get_source_file_name %d in %s and %d in %s\n",
c1.can_get_source_file_name, name1, c2.can_get_source_file_name, name2);
diff++;
}
if (c1.can_get_line_numbers
!= c2.can_get_line_numbers)
{
fprintf(stderr, "\t\tDIFF: can_get_line_numbers %d in %s and %d in %s\n",
c1.can_get_line_numbers, name1, c2.can_get_line_numbers, name2);
diff++;
}
if (c1.can_get_source_debug_extension
!= c2.can_get_source_debug_extension)
{
fprintf(stderr, "\t\tDIFF: can_get_source_debug_extension %d in %s and %d in %s\n",
c1.can_get_source_debug_extension, name1, c2.can_get_source_debug_extension, name2);
diff++;
}
if (c1.can_access_local_variables
!= c2.can_access_local_variables)
{
fprintf(stderr, "\t\tDIFF: can_access_local_variables %d in %s and %d in %s\n",
c1.can_access_local_variables, name1, c2.can_access_local_variables, name2);
diff++;
}
if (c1.can_maintain_original_method_order
!= c2.can_maintain_original_method_order)
{
fprintf(stderr, "\t\tDIFF: can_maintain_original_method_order %d in %s and %d in %s\n",
c1.can_maintain_original_method_order, name1, c2.can_maintain_original_method_order, name2);
diff++;
}
if (c1.can_generate_single_step_events
!= c2.can_generate_single_step_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_single_step_events %d in %s and %d in %s\n",
c1.can_generate_single_step_events, name1, c2.can_generate_single_step_events, name2);
diff++;
}
if (c1.can_generate_exception_events
!= c2.can_generate_exception_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_exception_events %d in %s and %d in %s\n",
c1.can_generate_exception_events, name1, c2.can_generate_exception_events, name2);
diff++;
}
if (c1.can_generate_frame_pop_events
!= c2.can_generate_frame_pop_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_frame_pop_events %d in %s and %d in %s\n",
c1.can_generate_frame_pop_events, name1, c2.can_generate_frame_pop_events, name2);
diff++;
}
if (c1.can_generate_breakpoint_events
!= c2.can_generate_breakpoint_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_breakpoint_events %d in %s and %d in %s\n",
c1.can_generate_breakpoint_events, name1, c2.can_generate_breakpoint_events, name2);
diff++;
}
if (c1.can_suspend
!= c2.can_suspend)
{
fprintf(stderr, "\t\tDIFF: can_suspend %d in %s and %d in %s\n",
c1.can_suspend, name1, c2.can_suspend, name2);
diff++;
}
if (c1.can_redefine_any_class
!= c2.can_redefine_any_class)
{
fprintf(stderr, "\t\tDIFF: can_redefine_any_class %d in %s and %d in %s\n",
c1.can_redefine_any_class, name1, c2.can_redefine_any_class, name2);
diff++;
}
if (c1.can_get_current_thread_cpu_time
!= c2.can_get_current_thread_cpu_time)
{
fprintf(stderr, "\t\tDIFF: can_tag_objects %d in %s and %d in %s\n",
c1.can_tag_objects, name1, c2.can_tag_objects, name2);
diff++;
}
if (c1.can_get_thread_cpu_time
!= c2.can_get_thread_cpu_time)
{
fprintf(stderr, "\t\tDIFF: can_tag_objects %d in %s and %d in %s\n",
c1.can_tag_objects, name1, c2.can_tag_objects, name2);
diff++;
}
if (c1.can_generate_method_entry_events
!= c2.can_generate_method_entry_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_method_entry_events %d in %s and %d in %s\n",
c1.can_generate_method_entry_events, name1, c2.can_generate_method_entry_events, name2);
diff++;
}
if (c1.can_generate_method_exit_events
!= c2.can_generate_method_exit_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_method_exit_events %d in %s and %d in %s\n",
c1.can_generate_method_exit_events, name1, c2.can_generate_method_exit_events, name2);
diff++;
}
if (c1.can_generate_all_class_hook_events
!= c2.can_generate_all_class_hook_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_all_class_hook_events %d in %s and %d in %s\n",
c1.can_generate_all_class_hook_events, name1, c2.can_generate_all_class_hook_events, name2);
diff++;
}
if (c1.can_generate_compiled_method_load_events
!= c2.can_generate_compiled_method_load_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_compiled_method_load_events %d in %s and %d in %s\n",
c1.can_generate_compiled_method_load_events, name1, c2.can_generate_compiled_method_load_events, name2);
diff++;
}
if (c1.can_generate_monitor_events
!= c2.can_generate_monitor_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_monitor_events %d in %s and %d in %s\n",
c1.can_generate_monitor_events, name1, c2.can_generate_monitor_events, name2);
diff++;
}
if (c1.can_generate_vm_object_alloc_events
!= c2.can_generate_vm_object_alloc_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_vm_object_alloc_events %d in %s and %d in %s\n",
c1.can_generate_vm_object_alloc_events, name1, c2.can_generate_vm_object_alloc_events, name2);
diff++;
}
if (c1.can_generate_native_method_bind_events
!= c2.can_generate_native_method_bind_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_native_method_bind_events %d in %s and %d in %s\n",
c1.can_generate_native_method_bind_events, name1, c2.can_generate_native_method_bind_events, name2);
diff++;
}
if (c1.can_generate_garbage_collection_events
!= c2.can_generate_garbage_collection_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_garbage_collection_events %d in %s and %d in %s\n",
c1.can_generate_garbage_collection_events, name1, c2.can_generate_garbage_collection_events, name2);
diff++;
}
if (c1.can_generate_object_free_events
!= c2.can_generate_object_free_events)
{
fprintf(stderr, "\t\tDIFF: can_generate_object_free_events %d in %s and %d in %s\n",
c1.can_generate_object_free_events, name1, c2.can_generate_object_free_events, name2);
diff++;
}
if (0 != diff)
{
fprintf(stderr, "\t\tDIFF: capabilities %s and %s has %d differences\n", name1, name2, diff);
}
else
{
fprintf(stderr, "\t\tDIFF: capabilities %s and %s are identical\n", name1, name2);
}
return diff;
}
void print_capabilities(jvmtiCapabilities c, const char* name)
{
fprintf(stderr, "\t\t%s.can_tag_objects = %d\n",
name, c.can_tag_objects);
fprintf(stderr, "\t\t%s.can_generate_field_modification_events = %d\n",
name, c.can_generate_field_modification_events);
fprintf(stderr, "\t\t%s.can_generate_field_access_events = %d\n",
name, c.can_generate_field_access_events);
fprintf(stderr, "\t\t%s.can_get_bytecodes = %d\n",
name, c.can_get_bytecodes);
fprintf(stderr, "\t\t%s.can_get_synthetic_attribute = %d\n",
name, c.can_get_synthetic_attribute);
fprintf(stderr, "\t\t%s.can_get_owned_monitor_info = %d\n",
name, c.can_get_owned_monitor_info);
fprintf(stderr, "\t\t%s.can_get_current_contended_monitor = %d\n",
name, c.can_get_current_contended_monitor);
fprintf(stderr, "\t\t%s.can_get_monitor_info = %d\n",
name, c.can_get_monitor_info);
fprintf(stderr, "\t\t%s.can_pop_frame = %d\n",
name, c.can_pop_frame);
fprintf(stderr, "\t\t%s.can_redefine_classes = %d\n",
name, c.can_redefine_classes);
fprintf(stderr, "\t\t%s.can_signal_thread = %d\n",
name, c.can_signal_thread);
fprintf(stderr, "\t\t%s.can_get_source_file_name = %d\n",
name, c.can_get_source_file_name);
fprintf(stderr, "\t\t%s.can_get_line_numbers = %d\n",
name, c.can_get_line_numbers);
fprintf(stderr, "\t\t%s.can_get_source_debug_extension = %d\n",
name, c.can_get_source_debug_extension);
fprintf(stderr, "\t\t%s.can_access_local_variables = %d\n",
name, c.can_access_local_variables);
fprintf(stderr, "\t\t%s.can_maintain_original_method_order = %d\n",
name, c.can_maintain_original_method_order);
fprintf(stderr, "\t\t%s.can_generate_single_step_events = %d\n",
name, c.can_generate_single_step_events);
fprintf(stderr, "\t\t%s.can_generate_exception_events = %d\n",
name, c.can_generate_exception_events);
fprintf(stderr, "\t\t%s.can_generate_frame_pop_events = %d\n",
name, c.can_generate_frame_pop_events);
fprintf(stderr, "\t\t%s.can_generate_breakpoint_events = %d\n",
name, c.can_generate_breakpoint_events);
fprintf(stderr, "\t\t%s.can_suspend = %d\n",
name, c.can_suspend);
fprintf(stderr, "\t\t%s.can_redefine_any_class = %d\n",
name, c.can_redefine_any_class);
fprintf(stderr, "\t\t%s.can_tag_objects = %d\n",
name, c.can_tag_objects);
fprintf(stderr, "\t\t%s.can_tag_objects = %d\n",
name, c.can_tag_objects);
fprintf(stderr, "\t\t%s.can_generate_method_entry_events = %d\n",
name, c.can_generate_method_entry_events);
fprintf(stderr, "\t\t%s.can_generate_method_exit_events = %d\n",
name, c.can_generate_method_exit_events);
fprintf(stderr, "\t\t%s.can_generate_all_class_hook_events = %d\n",
name, c.can_generate_all_class_hook_events);
fprintf(stderr, "\t\t%s.can_generate_compiled_method_load_events = %d\n",
name, c.can_generate_compiled_method_load_events);
fprintf(stderr, "\t\t%s.can_generate_monitor_events = %d\n",
name, c.can_generate_monitor_events);
fprintf(stderr, "\t\t%s.can_generate_vm_object_alloc_events = %d\n",
name, c.can_generate_vm_object_alloc_events);
fprintf(stderr, "\t\t%s.can_generate_native_method_bind_events = %d\n",
name, c.can_generate_native_method_bind_events);
fprintf(stderr, "\t\t%s.can_generate_garbage_collection_events = %d\n",
name, c.can_generate_garbage_collection_events);
fprintf(stderr, "\t\t%s.can_generate_object_free_events = %d\n",
name, c.can_generate_object_free_events);
}
/*
* Function for making ZERO capabilities
*/
void make_caps_zero(jvmtiCapabilities* c1)
{
memset(c1, 0, sizeof(jvmtiCapabilities));
return;
}
/*
* Function for making SET capabilities
*/
void make_caps_set_all(jvmtiCapabilities* c1)
{
memset(c1, 0xff, sizeof(jvmtiCapabilities));
return;
}
/*
* Check Phase
* 1. special phase parameter is
* 0 - any phases (no check)
* 1 - ONLOAD only
* 2 - ONLOAD & LIVE
* 3 - START & LIVE
* 4 - LIVE only
*/
bool check_phase_debug(jvmtiEnv* jvmti_env, int phase_param, bool is_debug)
{
jvmtiPhase phase;
jvmtiError result = jvmti_env->GetPhase(&phase);
if (is_debug)
{
fprintf(stderr, "\tnative: GetPhase result = %d (must be zero) \n", result);
fprintf(stderr, "\tnative: current phase is %d (must be 4 (LIVE-phase)) \n", phase);
}
if (result != JVMTI_ERROR_NONE) return false;
if (phase_param)
{
if (((phase_param == 1) && (phase == JVMTI_PHASE_ONLOAD)) ||
((phase_param == 2) && (phase == JVMTI_PHASE_ONLOAD) && (phase == JVMTI_PHASE_LIVE)) ||
((phase_param == 3) && (phase == JVMTI_PHASE_START) && (phase == JVMTI_PHASE_LIVE)) ||
((phase_param == 4) && (phase == JVMTI_PHASE_LIVE))) return true;
else
return false;
}
return true;
}
bool check_phase_and_method_debug(jvmtiEnv* jvmti_env, jmethodID method, int phase_param,
const char* exp_name, bool is_debug)
{
char* name;
char* signature;
char* generic;
if (!check_phase_debug(jvmti_env, phase_param, is_debug))
return false;
jvmtiError result = jvmti_env->GetMethodName(method, &name, &signature, &generic);
if (is_debug)
{
fprintf(stderr, "\tnative: GetMethodName result = %d (must be zero) \n", result);
fprintf(stderr, "\tnative: method name is %s \n", name);
fprintf(stderr, "\tnative: signature name is %s \n", signature);
fprintf(stderr, "\tnative: generic name is %s \n", generic);
fflush(stderr);
}
if (result != JVMTI_ERROR_NONE) return false;
if (strcmp(name, exp_name))
return false;
else
return true;
}
bool check_phase_and_thread_debug(jvmtiEnv* jvmti_env, jthread thread, int phase_param,
const char* exp_name, bool is_debug)
{
jvmtiThreadInfo tinfo;
if (!check_phase_debug(jvmti_env, phase_param, is_debug))
return false;
jvmtiError result = jvmti_env->GetThreadInfo(thread, &tinfo);
if (is_debug)
{
fprintf(stderr, "\tnative: GetThreadInfo result = %d (must be zero) \n", result);
fprintf(stderr, "\tnative: current thread name is %s (must be zero) \n", tinfo.name);
}
if (strcmp(tinfo.name, exp_name) || (result != JVMTI_ERROR_NONE))
return false;
else
return true;
}
/*
jthread create_not_alive_thread(JNIEnv* jni_env, jvmtiEnv* jvmti_env)
{
jclass clazz;
jmethodID mid;
jthread thread;
fprintf(stderr, "\tnative: JNI: funcs start\n");
clazz = jni_env->FindClass("java/lang/Thread");
if (!clazz) return NULL;
fprintf(stderr, "\tnative: JNI: FindClass - Ok\n");
mid = jni_env->GetMethodID(clazz, "<init>", "()V");
if (!mid) return NULL;
fprintf(stderr, "\tnative: JNI: GetMethodID - Ok\n");
thread = jni_env->NewObject(clazz, mid, "native_agent_thread");
if (!thread) return NULL;
fprintf(stderr, "\tnative: JNI: NewObject - Ok\n");
return thread;
}
*/
bool is_needed_field_found(jvmtiEnv* jvmti_env, const char* filename, const char* fieldname,
jclass* myclass, jfieldID* myfield, bool is_debug)
{
jint class_count;
jclass* classes;
jclass my_class = NULL;
char* source_name;
jint field_count;
jfieldID* fields;
jfieldID my_field = NULL;
jvmtiError result = jvmti_env->GetLoadedClasses(&class_count, &classes);
fprintf(stderr, "\tnative: GetLoadedClasses result = %d (must be zero) \n", result);
fprintf(stderr, "\tnative: class_count is %d \n", class_count);
fprintf(stderr, "\tnative: classes is %p \n", classes);
fflush(stderr);
if ( result != JVMTI_ERROR_NONE ) return false;
for (int i = 0; i < class_count; i++)
{
result = jvmti_env->GetSourceFileName(classes[i], &source_name);
if (is_debug)
{
fprintf(stderr, "\tnative: GetSourceFileName result = %d (must be zero) \n", result);
fprintf(stderr, "\tnative: source_name is %s \n", source_name);
fprintf(stderr, "\tnative: classes is %p \n", classes);
fflush(stderr);
}
if (result != JVMTI_ERROR_NONE) continue;
if (!strcmp(source_name, filename))
{
fprintf(stderr, "\tnative: GetSourceFileName result = %d (must be zero) \n", result);
fprintf(stderr, "\tnative: source_name is %s \n", source_name);
fprintf(stderr, "\tnative: classes is %p \n", classes);
fflush(stderr);
my_class = classes[i];
break;
}
}
result = jvmti_env->GetClassFields(my_class, &field_count, &fields);
fprintf(stderr, "\tnative: GetClassFields result = %d (must be zero) \n", result);
fprintf(stderr, "\tnative: fields_ptr is %p \n", fields);
fprintf(stderr, "\tnative: field_count_ptr is %d \n", field_count);
fprintf(stderr, "\tnative: my_class is %p \n", my_class);
fflush(stderr);
if ( result != JVMTI_ERROR_NONE ) return false;
for (int j = 0; j < field_count; j++)
{
char* name;
char* signature;
char* generic;
result = jvmti_env->GetFieldName(my_class, fields[j], &name, &signature, &generic);
if (is_debug)
{
fprintf(stderr, "\tnative: GetFieldName result = %d (must be zero) \n", result);
fprintf(stderr, "\tnative: classes is %p \n", my_class);
fprintf(stderr, "\tnative: fields_ptr[%d] is %p \n", j, fields[j]);
fprintf(stderr, "\tnative: field name is %s \n", name);
fprintf(stderr, "\tnative: field signature is %s \n", signature);
fprintf(stderr, "\tnative: field generic is %s \n", generic);
fflush(stderr);
}
if ( result != JVMTI_ERROR_NONE ) continue;
if (!strcmp(name, fieldname))
{
fprintf(stderr, "\tnative: GetFieldName result = %d (must be zero) \n", result);
fprintf(stderr, "\tnative: classes is %p \n", my_class);
fprintf(stderr, "\tnative: fields_ptr[%d] is %p \n", j, fields[j]);
fprintf(stderr, "\tnative: field name is %s \n", name);
fprintf(stderr, "\tnative: field signature is %s \n", signature);
fprintf(stderr, "\tnative: field generic is %s \n", generic);
fflush(stderr);
my_field = fields[j];
break;
}
}
if (!my_class || !my_field) return false;
*myclass = my_class;
*myfield = my_field;
return true;
}
jint func_for_Agent_OnLoad_JVMTI(JavaVM *vm, char *options, void *reserved, Callbacks* callbacks,
jvmtiEvent* events, jint size, const char* test_case_name, bool is_debug, jvmtiEnv** jvmti)
{
jvmtiEnv* jvmti_env;
jvmtiError result;
jvmtiCapabilities pc;
jvmtiEventCallbacks cb = {NULL};
//warning fix
int w_fix = sizeof(options);
w_fix += sizeof(reserved);
w_fix += sizeof (is_debug);
//
/* Getting of jvmti environment */
if (vm->GetEnv((void**)&jvmti_env, JVMTI_VERSION_1_0) != JNI_OK)
{
fprintf(stderr, "Failure of initialization of JVMTI environment");
return JNI_ERR;
}
*jvmti = jvmti_env;
result = jvmti_env->GetPotentialCapabilities(&pc);
if (result != JVMTI_ERROR_NONE)
{
fprintf(stderr, "\n\tERROR during the getting of potential capabilities");
fprintf(stderr, "\n\tERROR: test interupted");
fprintf(stderr, "\n\tnative: GetPotentialCapabilities error_code is %d",
result);
return JNI_ERR;
}
bool mentry = false, mexit = false, fpopnot = false;
for (jint mee_ind = 0; mee_ind < size; mee_ind++)
{
if (events[mee_ind] == JVMTI_EVENT_METHOD_ENTRY)
mentry = true;
if (events[mee_ind] == JVMTI_EVENT_METHOD_EXIT)
mexit = true;
if (events[mee_ind] == JVMTI_EVENT_FRAME_POP)
fpopnot = true;
}
if (!mentry)
pc.can_generate_method_entry_events = 0;
if (!mexit)
pc.can_generate_method_exit_events = 0;
if (!fpopnot)
pc.can_generate_frame_pop_events = 0;
result = jvmti_env->AddCapabilities(&pc);
if (result != JVMTI_ERROR_NONE)
{
fprintf(stderr, "\n\tERROR during the adding of all possible capabilities");
fprintf(stderr, "\n\tERROR: test interupted");
fprintf(stderr, "\n\tnative: AddCapabilities error_code is %d",
result);
return JNI_ERR;
}
memset(&cb, 0, sizeof(cb));
cb.SingleStep = callbacks->cbSingleStep;
cb.Breakpoint = callbacks->cbBreakpoint;
cb.FieldAccess = callbacks->cbFieldAccess;
cb.FieldModification = callbacks->cbFieldModification;
cb.FramePop = callbacks->cbFramePop;
cb.MethodEntry = callbacks->cbMethodEntry;
cb.MethodExit = callbacks->cbMethodExit;
cb.NativeMethodBind = callbacks->cbNativeMethodBind;
cb.Exception = callbacks->cbException;
cb.ExceptionCatch = callbacks->cbExceptionCatch;
cb.ThreadStart = callbacks->cbThreadStart;
cb.ThreadEnd = callbacks->cbThreadEnd;
cb.ClassLoad = callbacks->cbClassLoad;
cb.ClassPrepare = callbacks->cbClassPrepare;
cb.ClassFileLoadHook = callbacks->cbClassFileLoadHook;
cb.VMStart = callbacks->cbVMStart;
cb.VMInit = callbacks->cbVMInit;
cb.VMDeath = callbacks->cbVMDeath;
cb.CompiledMethodLoad = callbacks->cbCompiledMethodLoad;
cb.CompiledMethodUnload = callbacks->cbCompiledMethodUnload;
cb.DynamicCodeGenerated = callbacks->cbDynamicCodeGenerated;
cb.DataDumpRequest = callbacks->cbDataDumpRequest;
cb.MonitorContendedEnter = callbacks->cbMonitorContendedEnter;
cb.MonitorContendedEntered = callbacks->cbMonitorContendedEntered;
cb.MonitorWait = callbacks->cbMonitorWait;
cb.MonitorWaited = callbacks->cbMonitorWaited;
cb.VMObjectAlloc = callbacks->cbVMObjectAlloc;
cb.ObjectFree = callbacks->cbObjectFree;
cb.GarbageCollectionStart = callbacks->cbGarbageCollectionStart;
cb.GarbageCollectionFinish = callbacks->cbGarbageCollectionFinish;
for (int j = 0; j < size; j++)
{
result = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, events[j], NULL);
if (result == JVMTI_ERROR_NONE) continue;
fprintf(stderr, "\n\tERROR during the adding of SetEventNotificationMode");
fprintf(stderr, "\n\tERROR: test interupted");
fprintf(stderr, "\n\tnative: SetEventNotificationMode error_code is %d",
result);
return JNI_ERR;
}
result = jvmti_env->SetEventCallbacks(&cb, sizeof(cb));
if (result != JVMTI_ERROR_NONE)
{
fprintf(stderr, "\n\tERROR during the adding of SetEventCallbacks");
fprintf(stderr, "\n\tERROR: test interupted");
fprintf(stderr, "\n\tnative: SetEventCallbacks error_code is %d",
result);
return JNI_ERR;
}
fprintf(stderr, "\n----------------------------------------------------");
fprintf(stderr, "\ntest");
fprintf(stderr, " %s ", test_case_name);
fprintf(stderr, "is started\n{\n");
fflush(stderr);
return JNI_OK;
}
/*
* Universal agent function;
*/
jint func_for_Agent_OnLoad(JavaVM *vm, char *options, void *reserved, Callbacks* callbacks,
jvmtiEvent* events, jint size, const char* test_case_name, bool is_debug)
{
jvmtiEnv* jvmti_env;
jvmtiError result;
jvmtiCapabilities pc;
jvmtiEventCallbacks cb = {NULL};
//warning fix
int w_fix = sizeof(options);
w_fix += sizeof(reserved);
w_fix += sizeof (is_debug);
//
/* Getting of jvmti environment */
if (vm->GetEnv((void**)&jvmti_env, JVMTI_VERSION_1_0) != JNI_OK)
{
fprintf(stderr, "Failure of initialization of JVMTI environment");
return JNI_ERR;
}
result = jvmti_env->GetPotentialCapabilities(&pc);
if (result != JVMTI_ERROR_NONE)
{
fprintf(stderr, "\n\tERROR during the getting of potential capabilities");
fprintf(stderr, "\n\tERROR: test interupted");
fprintf(stderr, "\n\tnative: GetPotentialCapabilities error_code is %d",
result);
return JNI_ERR;
}
bool mentry = false, mexit = false, fpopnot = false;
for (jint mee_ind = 0; mee_ind < size; mee_ind++)
{
if (events[mee_ind] == JVMTI_EVENT_METHOD_ENTRY)
mentry = true;
if (events[mee_ind] == JVMTI_EVENT_METHOD_EXIT)
mexit = true;
if (events[mee_ind] == JVMTI_EVENT_FRAME_POP)
fpopnot = true;
}
if (!mentry)
pc.can_generate_method_entry_events = 0;
if (!mexit)
pc.can_generate_method_exit_events = 0;
if (!fpopnot)
pc.can_generate_frame_pop_events = 0;
result = jvmti_env->AddCapabilities(&pc);
if (result != JVMTI_ERROR_NONE)
{
fprintf(stderr, "\n\tERROR during the adding of all possible capabilities");
fprintf(stderr, "\n\tERROR: test interupted");
fprintf(stderr, "\n\tnative: AddCapabilities error_code is %d",
result);
return JNI_ERR;
}
memset(&cb, 0, sizeof(cb));
cb.SingleStep = callbacks->cbSingleStep;
cb.Breakpoint = callbacks->cbBreakpoint;
cb.FieldAccess = callbacks->cbFieldAccess;
cb.FieldModification = callbacks->cbFieldModification;
cb.FramePop = callbacks->cbFramePop;
cb.MethodEntry = callbacks->cbMethodEntry;
cb.MethodExit = callbacks->cbMethodExit;
cb.NativeMethodBind = callbacks->cbNativeMethodBind;
cb.Exception = callbacks->cbException;
cb.ExceptionCatch = callbacks->cbExceptionCatch;
cb.ThreadStart = callbacks->cbThreadStart;
cb.ThreadEnd = callbacks->cbThreadEnd;
cb.ClassLoad = callbacks->cbClassLoad;
cb.ClassPrepare = callbacks->cbClassPrepare;
cb.ClassFileLoadHook = callbacks->cbClassFileLoadHook;
cb.VMStart = callbacks->cbVMStart;
cb.VMInit = callbacks->cbVMInit;
cb.VMDeath = callbacks->cbVMDeath;
cb.CompiledMethodLoad = callbacks->cbCompiledMethodLoad;
cb.CompiledMethodUnload = callbacks->cbCompiledMethodUnload;
cb.DynamicCodeGenerated = callbacks->cbDynamicCodeGenerated;
cb.DataDumpRequest = callbacks->cbDataDumpRequest;
cb.MonitorContendedEnter = callbacks->cbMonitorContendedEnter;
cb.MonitorContendedEntered = callbacks->cbMonitorContendedEntered;
cb.MonitorWait = callbacks->cbMonitorWait;
cb.MonitorWaited = callbacks->cbMonitorWaited;
cb.VMObjectAlloc = callbacks->cbVMObjectAlloc;
cb.ObjectFree = callbacks->cbObjectFree;
cb.GarbageCollectionStart = callbacks->cbGarbageCollectionStart;
cb.GarbageCollectionFinish = callbacks->cbGarbageCollectionFinish;
for (int j = 0; j < size; j++)
{
result = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, events[j], NULL);
if (result == JVMTI_ERROR_NONE) continue;
fprintf(stderr, "\n\tERROR during the adding of SetEventNotificationMode");
fprintf(stderr, "\n\tERROR: test interupted");
fprintf(stderr, "\n\tnative: SetEventNotificationMode error_code is %d",
result);
return JNI_ERR;
}
result = jvmti_env->SetEventCallbacks(&cb, sizeof(cb));
if (result != JVMTI_ERROR_NONE)
{
fprintf(stderr, "\n\tERROR during the adding of SetEventCallbacks");
fprintf(stderr, "\n\tERROR: test interupted");
fprintf(stderr, "\n\tnative: SetEventCallbacks error_code is %d",
result);
return JNI_ERR;
}
fprintf(stderr, "\n----------------------------------------------------");
fprintf(stderr, "\ntest");
fprintf(stderr, " %s ", test_case_name);
fprintf(stderr, "is started\n{\n");
fflush(stderr);
return JNI_OK;
}
/*
* Universal VMDeath callback function;
*/
void func_for_callback_VMDeath(JNIEnv* jni_env, jvmtiEnv* jvmti_env,
const char* test_case_name, bool test, bool util)
{
//warning fix
int w_fix = 1;
w_fix += sizeof(jni_env);
w_fix += sizeof(jvmti_env);
//
fprintf(stderr, "\n\tTest of function ");
fprintf(stderr, "%s ", test_case_name);
fprintf(stderr, " : ");
fflush(stderr);
if (test && util)
fprintf(stderr, " passed \n");
else
fprintf(stderr, " failed \n");
fprintf(stderr, "\n} /* test ");
fprintf(stderr, "%s ", test_case_name);
fprintf(stderr, "is finished */ \n\n");
fflush(stderr);
return;
}
/* *********************************************************************** */