CDS and JVM-TI agent questions and crash
Michael Rasmussen
Michael.Rasmussen at roguewave.com
Mon Oct 15 21:14:16 UTC 2018
> I logged issue in JDK-8212200,
> https://bugs.openjdk.java.net/browse/JDK-8212200
> Thanks,
> Jiangli
Hi Jiangli,
Thanks -- though regarding your comment there, I don't know if it only applies when changing Object's bytes?
I did a small test (attached below) with adding a default method to Serializable, and it crashes as well, though differently -- don't know if what Volker mentioned fixes this though.
Running the below with CDS off, I get:
$ ../jdk/bin/java -Xshare:off -agentpath:./libagent.so Test.java
public default java.lang.Object java.io.Serializable._$_$_blah()
With it on, I get the following crash:
$ ../jdk/bin/java -Xshare:on -agentpath:./libagent.so Test.java
# Internal Error (.../src/hotspot/share/classfile/javaClasses.cpp:667), pid=277, tid=278
# assert(java_string->klass() == SystemDictionary::String_klass()) failed: must be java_string
/Michael
Stack trace:
V [libjvm.so+0xe80ea5] java_lang_String::equals(oop, unsigned short*, int)+0x85
V [libjvm.so+0x9e6e44] CompactHashtable<oop, char>::decode_entry(CompactHashtable<oop, char>*, unsigned int, char const*, int)+0x54
V [libjvm.so+0x167fae6] StringTable::lookup_shared(unsigned short*, int, unsigned int)+0x166
V [libjvm.so+0x16801df] StringTable::intern(Handle, unsigned short*, int, Thread*)+0x6f
V [libjvm.so+0x16802e3] StringTable::intern(Symbol*, Thread*)+0x53
V [libjvm.so+0xae9921] ConstantPool::uncached_string_at(int, Thread*)+0x31
V [libjvm.so+0xc4426c] fieldDescriptor::string_initial_value(Thread*) const+0x9c
V [libjvm.so+0xe88056] initialize_static_field(fieldDescriptor*, Handle, Thread*)+0x1c6
V [libjvm.so+0xe23819] InstanceKlass::do_local_static_fields(void (*)(fieldDescriptor*, Handle, Thread*), Handle, Thread*)+0xd9
V [libjvm.so+0xe70157] java_lang_Class::initialize_mirror_fields(Klass*, Handle, Handle, Thread*)+0x117
V [libjvm.so+0xe723c3] java_lang_Class::create_mirror(Klass*, Handle, Handle, Handle, Thread*)+0x723
V [libjvm.so+0x95b8fd] ClassFileParser::fill_instance_klass(InstanceKlass*, bool, Thread*)+0x1c8d
V [libjvm.so+0x95c12f] ClassFileParser::create_instance_klass(bool, Thread*)+0x5f
V [libjvm.so+0x118e5f5] KlassFactory::create_from_stream(ClassFileStream*, Symbol*, ClassLoaderData*, Handle, InstanceKlass const*, GrowableArray<Handle>*, Thread*)+0x615
V [libjvm.so+0x96b76c] ClassLoader::load_class(Symbol*, bool, Thread*)+0x1bc
V [libjvm.so+0x171a3e6] SystemDictionary::load_instance_class(Symbol*, Handle, Thread*)+0x5f6
V [libjvm.so+0x1718139] SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*)+0xa69
V [libjvm.so+0x1718662] SystemDictionary::resolve_or_null(Symbol*, Handle, Handle, Thread*)+0x42
V [libjvm.so+0x17187de] SystemDictionary::resolve_or_fail(Symbol*, Handle, Handle, bool, Thread*)+0x1e
V [libjvm.so+0x1718991] SystemDictionary::initialize_wk_klass(SystemDictionary::WKID, int, Thread*)+0x151
V [libjvm.so+0x1718af1] SystemDictionary::initialize_wk_klasses_until(SystemDictionary::WKID, SystemDictionary::WKID&, Thread*)+0x61
V [libjvm.so+0x1718d33] SystemDictionary::initialize_preloaded_classes(Thread*)+0x153
V [libjvm.so+0x17190ea] SystemDictionary::initialize(Thread*)+0x21a
V [libjvm.so+0x17a8140] Universe::genesis(Thread*)+0x5f0
V [libjvm.so+0x17a8b5c] universe2_init()+0x2c
V [libjvm.so+0xe1e558] init_globals()+0xa8
V [libjvm.so+0x1766d17] Threads::create_vm(JavaVMInitArgs*, bool*)+0x2d7
Sample code:
/* --- snip ---- */
#include <string.h>
#include <jni.h>
#include <jvmti.h>
static char *serializable_class_name = "java/io/Serializable";
/*
public interface java.io.Serializable {
default Object _$_$_blah() { return this; }
}
*/
static jbyte serializable_class_bytes[] = {
202, 254, 186, 190, 0, 0, 0, 55, 0, 10, 1, 0, 20, 106, 97, 118,
97, 47, 105, 111, 47, 83, 101, 114, 105, 97, 108, 105, 122, 97, 98, 108,
101, 7, 0, 1, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103,
47, 79, 98, 106, 101, 99, 116, 7, 0, 3, 1, 0, 17, 83, 101, 114,
105, 97, 108, 105, 122, 97, 98, 108, 101, 46, 106, 97, 118, 97, 1, 0,
9, 95, 36, 95, 36, 95, 98, 108, 97, 104, 1, 0, 20, 40, 41, 76,
106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116,
59, 1, 0, 4, 67, 111, 100, 101, 1, 0, 10, 83, 111, 117, 114, 99,
101, 70, 105, 108, 101, 6, 1, 0, 2, 0, 4, 0, 0, 0, 0, 0,
1, 0, 1, 0, 6, 0, 7, 0, 1, 0, 8, 0, 0, 0, 14, 0,
1, 0, 1, 0, 0, 0, 2, 42, 176, 0, 0, 0, 0, 0, 1, 0,
9, 0, 0, 0, 2, 0, 5
};
static jsize serializable_class_bytes_len = 183;
void JNICALL callback_ClassFileLoadHook(jvmtiEnv *jvmti, JNIEnv* env,
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) {
if (strcmp(serializable_class_name, name) == 0) {
*new_class_data_len = serializable_class_bytes_len;
(*jvmti)->Allocate(jvmti, *new_class_data_len, new_class_data);
memcpy(*new_class_data, serializable_class_bytes, *new_class_data_len);
}
}
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
jvmtiEnv *jvmti;
jint rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_9);
jvmtiCapabilities caps;
memset(&caps, 0, sizeof(caps));
caps.can_redefine_classes = 1;
caps.can_generate_all_class_hook_events = 1;
caps.can_generate_early_vmstart = 1;
caps.can_generate_early_class_hook_events = 1;
(*jvmti)->AddCapabilities(jvmti, &caps);
jvmtiEventCallbacks callbacks;
memset(&callbacks, 0, sizeof(callbacks));
callbacks.ClassFileLoadHook = &callback_ClassFileLoadHook;
(*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
(*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
return 0;
}
/* ---- snap --- */
import java.io.Serializable;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
Stream.of(Serializable.class.getDeclaredMethods()).forEach(System.out::println);
}
}
/* ---- snude ---- */
More information about the hotspot-dev
mailing list