RFR (S) 8173361: various crashes in JvmtiExport::post_compiled_method_load
coleen.phillimore at oracle.com
coleen.phillimore at oracle.com
Fri Nov 15 22:27:27 UTC 2019
Thanks Dan for looking at this.
On 11/15/19 11:29 AM, Daniel D. Daugherty wrote:
> On 11/15/19 7:48 AM, coleen.phillimore at oracle.com wrote:
>> I meant to add myself to the To list.
>>
>> On 11/15/19 7:39 AM, coleen.phillimore at oracle.com wrote:
>>>
>>>
>>> On 11/14/19 9:07 PM, Chris Plummer wrote:
>>>> Hi Coleen,
>>>>
>>>> Is it ok to end up missing some CompiledMethodLoad events? The spec
>>>> says:
>>>>
>>>> "Sent when a method is compiled and loaded into memory by the VM.
>>>> If it is unloaded, the CompiledMethodUnload event is sent. If it is
>>>> moved, the CompiledMethodUnload event is sent, followed by a new
>>>> CompiledMethodLoad event. Note that a single method may have
>>>> multiple compiled forms, and that this event will be sent for each
>>>> form. "
>>>>
>>>> So a method was still "compiled and loaded into memory", right? We
>>>> just didn't get the event out before it was too late. Is the
>>>> CompiledMethodUnload still sent?
>>>
>>> Yes, the CompiledMethodUnload event would be sent for this.
>>>
>>> My first version of my change reported the event without the extra
>>> information (inlining and some code blob address location maps).
>>> Maybe that would be better. Here it is and tested successfully
>>> with the testcase that crashed.
>>>
>>> open webrev at
>>> http://cr.openjdk.java.net/~coleenp/2019/8173361.02/webrev
>
> src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp
> No comments.
>
> src/hotspot/share/prims/jvmtiExport.cpp
> L2132: // It's not safe to look at metadata for unloaded methods.
> L2133: if (nm->method() == NULL) {
> L2134: return NULL;
> nit - The comment is about why we're returning NULL early so
> perhaps the comment should be inside the if-statement (between
> L2133 and L2134).
>
Sure, I can change that.
> In the previous version (01) you checked (!nm->is_alive()) in a
> different place. That function is defined:
>
> bool is_alive() const { return _state < unloaded; }
>
> And states like unloaded are defined like this:
>
> enum { not_installed = -1, // in construction, only the owner doing
> the construction is
> // allowed to advance state
> in_use = 0, // executable nmethod
> not_used = 1, // not entrant, but revivable
> not_entrant = 2, // marked for deoptimization but
> activations may still exist,
> // will be transformed to zombie when all
> activations are gone
> unloaded = 3, // there should be no activations, should
> not be called, will be
> // transformed to zombie by the sweeper,
> when not "locked in vm".
> zombie = 4 // no activations exist, nmethod is ready
> for purge
> };
>
> so by switching to (nm->method() == NULL) you are going more
> directly to whether there is useful data available, but it
> might be racier. I'm not sure at which state nm->method()
> starts to return NULL. I'm also not sure if nm->method() can
> return NULL for any of the earlier states, e.g., not_used.
>
> I agree with your earlier comment that nm->is_alive() seems
> safer. Your call on which to use.
I think my earlier comment was wrong. If the method is unloaded, the
_method field is zeroed before the unloaded _state is set. With
concurrent class unloading, this event posting can run at the same time
as make_unloaded(), if I'm reading this correctly.
I should actually use Atomic::load to get the _method, in both of the
places where I get the field.
The _method is also zeroed with make_zombie call but this is blocked out
by the nmethodLocker.
Thanks,
Coleen
>
> Thumbs up. My only non-theory comment is a nit so I don't need to
> see a new webrev.
>
> Dan
>
>
>>>
>>> The more I look at this code, the more problems I see.
>>> get_and_cache_jmethod_id() will send back a jmethodID from when the
>>> method was live. But like the class unloading event, a user cannot
>>> trust that the Method* in the jmethodID points to anything valid.
>>>
>>> So the spec for CompiledMethodLoad event should say for the method,
>>> like the CompiledMethodUnload event:
>>> Compiled method being unloaded. For identification of the compiled
>>> method only -- the class may be unloaded and therefore the method
>>> should not be used as an argument to further JNI or JVMTI functions.
>>>
>>> Or we don't send the event like 01. Either one doesn't crash.
>>>
>>> Thanks,
>>> Coleen
>>>
>>>>
>>>> thanks,
>>>>
>>>> Chris
>>>>
>>>> On 11/14/19 5:15 PM, coleen.phillimore at oracle.com wrote:
>>>>> Summary: Don't post information which uses metadata from unloaded
>>>>> nmethods
>>>>>
>>>>> Tested tier1-3 and 100 times with test that failed (reproduced
>>>>> failure without the fix).
>>>>>
>>>>> open webrev at
>>>>> http://cr.openjdk.java.net/~coleenp/2019/8173361.01/webrev
>>>>> bug link https://bugs.openjdk.java.net/browse/JDK-8173361
>>>>>
>>>>> Thanks,
>>>>> Coleen
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20191115/1d3238a5/attachment.html>
More information about the serviceability-dev
mailing list