Relates :
|
|
Relates :
|
|
Relates :
|
Note: this bug can be reproduced in JDK 17u only. JDK 17u repo: https://github.com/openjdk/jdk17u gcc version 10.3.0 (GCC) For some reason, it's no longer reproducible in JDK mainline. For a simpler reproducer in the JDK mainline, see the second comment below. The following patch causes a crash in the delete operation: --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -1257,6 +1257,8 @@ DumpTimeSharedClassInfo* SystemDictionaryShared::find_or_allocate_info_for_locke assert_lock_strong(DumpTimeTable_lock); if (_dumptime_table == NULL) { _dumptime_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeSharedClassTable(); + delete _dumptime_table; + _dumptime_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeSharedClassTable(); } return _dumptime_table->find_or_allocate_info_for(k, _dump_in_progress); } Gcc generates the following code: 0x00007ffff6681adc <+14>: mov $0x2,%esi 0x00007ffff6681ae1 <+19>: mov $0x1f0a8,%edi 0x00007ffff6681ae6 <+24>: callq 0x7ffff5a2e7dc <ResourceObj::operator new(unsigned long, ResourceObj::allocation_type, MEMFLAGS)> 0x00007ffff6681aeb <+29>: mov %rax,%rbx 0x00007ffff6681aee <+32>: test %rbx,%rbx 0x00007ffff6681af1 <+35>: je 0x7ffff6681b10 <foofoo()+66> 0x00007ffff6681af3 <+37>: mov %rbx,%rax 0x00007ffff6681af6 <+40>: mov $0x1f0a8,%edx 0x00007ffff6681afb <+45>: mov $0x0,%esi 0x00007ffff6681b00 <+50>: mov %rax,%rdi >>>0x00007ffff6681b03 <+53>: callq 0x7ffff5827470 <memset@plt> <<<<<<<<<<<<<<<<< HERE 0x00007ffff6681b08 <+58>: mov %rbx,%rdi 0x00007ffff6681b0b <+61>: callq 0x7ffff6687db8 <DumpTimeSharedClassTable::DumpTimeSharedClassTable()> ResourceObj::_allocation_t is initialized inside the new operator, and it gets trashed by the subsequent call to memset(). As a result, we get an assertion failure inside the destructor: $ java -Xshare:dump [....] # Internal Error (/jdk2/mnd/open/src/hotspot/share/memory/allocation.cpp:190), pid=10343, tid=10344 # assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this) failed: lost resource object V [libjvm.so+0x4ebb89] ResourceObj::get_allocation_type() const+0x31 V [libjvm.so+0x4ec0e8] ResourceObj::allocated_on_C_heap() const+0x18 V [libjvm.so+0x4eb9f0] ResourceObj::operator delete(void*)+0x18 V [libjvm.so+0x113eb17] SystemDictionaryShared::find_or_allocate_info_for_locked(InstanceKlass*)+0x8b However, adding a dummy constructor for DumpTimeSharedClassTable makes the problem goes away. The memset is no longer generated by gcc. ================== --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -219,6 +219,7 @@ class DumpTimeSharedClassTable: public ResourceHashtable< int _builtin_count; int _unregistered_count; public: + DumpTimeSharedClassTable(int dummy) {} DumpTimeSharedClassInfo* find_or_allocate_info_for(InstanceKlass* k, bool dump_in_progress) { bool created = false; DumpTimeSharedClassInfo* p; @@ -1256,7 +1257,9 @@ DumpTimeSharedClassInfo* SystemDictionaryShared::find_or_allocate_info_for(Insta DumpTimeSharedClassInfo* SystemDictionaryShared::find_or_allocate_info_for_locked(InstanceKlass* k) { assert_lock_strong(DumpTimeTable_lock); if (_dumptime_table == NULL) { - _dumptime_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeSharedClassTable(); + _dumptime_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeSharedClassTable(0); + delete _dumptime_table; + _dumptime_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeSharedClassTable(0); } return _dumptime_table->find_or_allocate_info_for(k, _dump_in_progress); }
|