RFR 8082782: vm crash on StressRedefineWithoutBytecodeCorruption fails with assert(((Metadata*)obj)->is_, valid()) failed: obj is valid

Daniel D. Daugherty daniel.daugherty at oracle.com
Thu Jul 23 16:08:50 UTC 2015


And one more reply...


On 7/23/15 9:52 AM, Coleen Phillimore wrote:
>
> One comment on your one comment...
>
> On 7/23/15 9:04 AM, Daniel D. Daugherty wrote:
>> Just one thing below...
>>
>>
>> On 7/22/15 7:25 PM, Coleen Phillimore wrote:
>>>
>>> Dan,
>>>
>>> Thank you for the quick code review.
>>>
>>> On 7/22/15 8:35 PM, Daniel D. Daugherty wrote:
>>>> On 7/22/15 10:20 AM, Coleen Phillimore wrote:
>>>>> Summary: Walk compile task for Method* to not deallocate, store 
>>>>> methods in methodHandle while compile task is being created
>>>>
>>>> Wait... 'while compile task is being created'...
>>>> You're holding these handles while the compile task
>>>> is being removed... Am I confused here?
>>>>
>>>
>>> No, you're not confused, you are right, we're getting the compile 
>>> task is being taken off the compile queue.
>>>>
>>>>> I couldn't reproduce this or write a test with the exact timing 
>>>>> needed to get this crash, but this is what the stack trace and 
>>>>> code inspection tells me what happened. Reran all redefinition and 
>>>>> internal tonga 'quick' tests on the change with no regression.
>>>>>
>>>>> open webrev at http://cr.openjdk.java.net/~coleenp/8082782.01/
>>>>
>>>> src/share/vm/compiler/compileBroker.hpp
>>>>     No comments.
>>>>
>>>> src/share/vm/compiler/compileBroker.cpp
>>>>     Is there a reason to have save_method and save_hot_method
>>>>     defined all the way up at lines 671-672 instead of
>>>>     being defined and init'ed on lines 710-711?
>>>
>>> The methodHandle destructor has to run after the mutexLocker 
>>> destructor.   The methodHandle destructors take it off the list of 
>>> Methods to mark on stack to not deallocate, but have to run after 
>>> the MutexLocker destructor so it has to be declared first.
>>
>> Ahhh... That deserves a comment, but...
>> I ran into a case before where I needed:
>>
>>    definition objectA;
>>    definition objectB;
>>
>>    <other code>
>>    definition ret_value = something;
>>
>>    return ret_value
>>    <objectB destructor>
>>    <objectA destructor>
>>
>> but I couldn't find anything in C++ that guaranteed that the
>> destructors are run in the opposite order of definition.
>>
>> What I ended up doing was this:
>>
>>    definition objectA;
>>    definition ret_value;
>>    { // make sure objectB is destructed before objectA
>>      definition objectB;
>>
>>      <other code>
>>      ret_value = something;
>>    } <objectB destructor>
>>
>>    return ret_value
>>    <objectA destructor>
>>
>> You might have better luck finding such a C++ guarantee,
>> but if not...
>
> It's in the C++ standard and guaranteed.  No {} are required, 
> especially for your case.  For the case I have with assignment, it 
> could go wrong if the assignment operator is defined incorrectly (but 
> I believe methodHandle assignment operator is correct).
>
> http://en.cppreference.com/w/cpp/language/destructor

I'm guessing that this is the wording you're referencing:

 > Destruction sequence
 >
 > For both user-defined or implicitly-defined destructors, after
 > the body of the destructor is executed, the compiler calls the
 > destructors for all non-static non-variant members of the class,
 > in reverse order of declaration, then it calls the destructors
 > of all direct base classes in reverse order of construction
 > (which in turn call the destructors of their members and their
 > base classes, etc), and then, if this object is of most-derived
 > class, it calls the destructors of all virtual bases.
 >
 > Even when the destructor is called directly (e.g. obj.~Foo();),
 > the return statement in ~Foo() does not return control to the
 > caller immediately: it calls all those member and base
 > destructors first.


The above wording applies to a class, its superclass and
the members of the class. I don't see any wording about
unrelated variables of different types... The above phrase
"in reverse order of declaration" is used when talking
about members of the class.

I don't see any wording here that guarantee a particular order
with respect to order of local variable declarations. It could
be buried there somewhere else, but I don't see it.

Dan


>
> Coleen
>>
>> Dan
>>
>>>>
>>>>     L708:   // Save method pointer across
>>>>         Typo: 'pointer' -> 'pointers'
>>>
>>> Fixed.
>>>>
>>>>     So the idea of this fix is that you're holding methodHandles for
>>>>     these method pointers while removing the task because removing
>>>>     the task can go to a safepoint. While we're at that safepoint,
>>>>     a RedefineClasses call can come along and try and access/use the
>>>>     method pointers. 
>>>
>>> RedefineClasses will walk the previous versions of the method's 
>>> holder class and determine that nothing is using the old methods, 
>>> and put them on the list to deallocate the next time we unload 
>>> classes.   The methodHandle marks these methods as being used 
>>> (on_stack) across these safepoints so they stick around.
>>>
>>>> If we didn't have methodHandles on them, they
>>>>     could be freed by the time RedefineClasses tries to access/use
>>>>     them...
>>>>
>>>
>>> They'd be freed by the time the following code uses them (if you 
>>> redefine the class and subsequently do some class unloading GC, not 
>>> terribly likely but can happen in this small window and seems to 
>>> have happened in this crash from the dump).  It's like a naked 
>>> methodOop before permgen elimination, except it doesn't move, it 
>>> gets deallocated.
>>>
>>> The is_valid() debugging function partially detects that something 
>>> has written over this bit of the metadata. Deallocation writes 0xf5 
>>> over the stuff it deallocates.
>>>
>>>> Do I have this right? Ouch and nice find.
>>>>
>>> thanks!
>>>> src/share/vm/runtime/thread.cpp
>>>>     No comments.
>>>>
>>>>
>>>
>>> Thank you!!
>>> Coleen
>>>
>>>>> bug link https://bugs.openjdk.java.net/browse/JDK-8082782
>>>>>
>>>>> Thanks,
>>>>> Coleen
>>>>
>>>
>>
>



More information about the hotspot-dev mailing list