/* dump classes */ static void m_dump_class(char *arg) { struct class *clptr = NULL; if(arg) { if(chars_isdigit(*arg)) clptr = class_find_id(atoi(arg)); else clptr = class_find_name(arg); } class_dump(clptr); }
/* * Instrument classfile to invoke new object & array creation hooks in <cinit> of java.lang.Object */ void instrument_classfile( jvmtiEnv* jvmti, JNIEnv* jni , jclass class_being_redefined, jobject loader , const char* name, jobject protection_domain , jint class_data_len, const unsigned char* class_data , jint* new_class_data_len, unsigned char** new_class_data ) { static size_t classfile_index; // determine classname const char* classname = get_classname( name, class_data, class_data_len ); std::string internal_classname("L"); internal_classname += classname; internal_classname += ";"; xpr::sregex thread_filter = xpr::sregex::compile( eraser::agent::instance()->thread_filter_regex_ ); bool is_thread = xpr::regex_match( internal_classname, thread_filter ); bool obj_match = strcmp(classname, "java/lang/Object") == 0; if( !( is_thread || obj_match ) ) { free((void*)classname); return; } logger::instance()->level(200) << classname << std::boolalpha << " is_thread= " << is_thread << " obj_match= " << obj_match << std::endl; // prevent self-instrumentation if( strcmp(classname, PROXY_CLASS) == 0 ) { free((void*)classname); return; } unsigned char* new_image = 0; long new_length = 0; *new_class_data_len = 0; *new_class_data = 0; classfile_index++; bool is_system_class = ( agent::instance()->phase() < JVMTI_PHASE_START ); // go instrument if( obj_match ) java_crw_demo( classfile_index, classname , class_data, class_data_len , is_system_class , PROXY_CLASS , "L" PROXY_CLASS ";" , 0, 0 , 0, 0 , NEW_OBJ_METHOD, "(Ljava/lang/Object;)V" , NEW_ARR_METHOD, "(Ljava/lang/Object;)V" , &new_image , &new_length , 0, 0 ); else if( is_thread ) java_crw_demo( classfile_index, classname , class_data, class_data_len , is_system_class , PROXY_CLASS , "L" PROXY_CLASS ";" , MONITOR_ENTER, "(Ljava/lang/Object;)V" , MONITOR_EXIT, "(Ljava/lang/Object;)V" , 0, 0 , 0, 0 , &new_image , &new_length , 0, 0 ); else BOOST_ASSERT( false ); // memcpy transformed classfile to jvmti allocated memory if( new_length > 0 ) { # if defined( ERASER_DEBUG ) std::ofstream class_dump( "dump", std::ofstream::binary ); class_dump.write( (const char*)new_image, (std::streamsize)new_length ); class_dump.close(); # endif unsigned char *jvmtispace = (unsigned char *)allocate( jvmti, (jint)new_length ); memcpy( (void*)jvmtispace, (void*)new_image, new_length ); *new_class_data_len = new_length; *new_class_data = jvmtispace; } if( new_image != 0 ) free(new_image); free((void*)classname); }