On Tue, 1 Dec 2020 10:02:08 GMT, Kim Barrett <kbarr...@openjdk.org> wrote:

>> That isn't quite what I asked. The claim is that 
>> `remove_dead_entries_locked` needs to recheck `is_enabled` if 
>> `post_object_free` is true in case the enabled state changed from true to 
>> false. But I can't see how such a situation can arise. In 
>> `flush_object_free_events` we only call `remove_dead_entries(false)` and 
>> that is when events were seen to be disabled.
>
> I think you've missed the indirect remove_dead_entries(true) via
> post_dead_objects_on_vm_thread() in the enabled case, over on the vmthread.
> And that's exactly the case that shows up in the hs_err file.  The assert
> happens on the vmthread, in the VMOp used by post_dead_entries_xxx:
> 
> Stack: [0x00007f07456c6000,0x00007f07457c6000],  sp=0x00007f07457c48c0,  free 
> space=1018k
> Native frames: (J=compiled Java code, A=aot compiled Java code, 
> j=interpreted, Vv=VM code, C=native code)
> V  [libjvm.so+0x11e92fc]  JvmtiExport::post_object_free(JvmtiEnv*, long)+0x8c
> V  [libjvm.so+0x12293b2]  JvmtiTagMapTable::remove_dead_entries(JvmtiEnv*, 
> bool)+0x192
> V  [libjvm.so+0x12212cd]  VM_JvmtiPostObjectFree::doit()+0x5d
> V  [libjvm.so+0x198469a]  VM_Operation::evaluate()+0x18a
> V  [libjvm.so+0x19a7e7f]  VMThread::evaluate_operation(VM_Operation*)+0x17f
> V  [libjvm.so+0x19a88cc]  VMThread::inner_execute(VM_Operation*)+0x17c
> V  [libjvm.so+0x19a8b85]  VMThread::loop()+0xb5
> V  [libjvm.so+0x19a8cba]  VMThread::run()+0xca
> V  [libjvm.so+0x1893db0]  Thread::call_run()+0x100
> V  [libjvm.so+0x1574796]  thread_native_entry(Thread*)+0x116

In flush_object_free_events, we read that the event is enabled outside the 
lock, then we call remove_dead_entries(true).  Then remove_dead_entries() gets 
the table lock and proceeds to walk the table and post the events.  Another 
thread could be disabling the event while this is happening, leading to the 
assert.
So the fix is to make enabling/disabling the event be under the same table 
lock, and recheck that the event is enabled under that lock in 
remove_dead_entries_locked.

-------------

PR: https://git.openjdk.java.net/jdk/pull/1439

Reply via email to