JDK-8246381 : VM crashes with "Current BasicObjectLock* below than low_mark"
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8,11,15
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-06-02
  • Updated: 2020-10-05
  • Resolved: 2020-07-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 15 JDK 16
11.0.10-oracleFixed 15 b33Fixed 16Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
runtime/Unsafe/InternalErrorTest.java run in GraalVM Jit mode crashed with

#  Internal Error (/opt/mach5/mesos/work_dir/slaves/805146e6-8fdb-4552-bf9e-385b73cf7129-S372/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/1223c8b0-4f7d-415f-9cce-2d6b8934587c/runs/69f61d25-2ff0-4b07-b318-1bb5963850b6/workspace/open/src/hotspot/share/runtime/frame.cpp:1122), pid=8964, tid=8984
#  guarantee(current >= low_mark) failed: Current BasicObjectLock* below than low_mark
#
# JRE version: Java(TM) SE Runtime Environment (15.0) (fastdebug build 15-internal+0-2020-06-02-1800592.ekaterina.pavlova.jdk.jdk)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 15-internal+0-2020-06-02-1800592.ekaterina.pavlova.jdk.jdk, mixed mode, sharing, tiered, jvmci, jvmci compiler, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0xa924e4]  frame::interpreter_frame_verify_monitor(BasicObjectLock*) const+0xc4

The failure seems to be observed only on Linux.

I was also able easy reproduce it with b24 but not with b23.
Comments
Fix Request (11u) I would like to backport this patch to 11u for parity with Oracle 11.0.10. The original patch does not apply cleanly. 11u patch has been reviewed by Paul.
28-09-2020

11u code review: https://mail.openjdk.java.net/pipermail/jdk-updates-dev/2020-September/003882.html
28-09-2020

URL: https://hg.openjdk.java.net/jdk/jdk15/rev/f8cffefd6e9b User: jcm Date: 2020-07-16 15:29:20 +0000
16-07-2020

//The proposed fix is fine as far as it goes. I'm just saying there may be more to examine here for those other issues. The build_interpreter_method_data code takes a lock which means the thread can block, which means it can safepoint/handshake, which _might_ mean it can install an async exception. I'm trying to check on the details of that, but identifying the paths where we can potentially install async exceptions is non-trivial to work out.// hmm. i am in assumption that pending_exception for async will be set only at VM to Java transition and that should be handled in VM to Interpreter exit or VM to compiled code (in compiled code) and it shouldn't float without handling in interpreter or compiled code except for PopFrame and EarlyReturn. In the failures i see, I presume handshaking happened in normal blocked state and async exception was installed by the other thread. but pending_exception was never set or handled later as it didn't have an opportunity to do so.
15-07-2020

I have some failures for webrev.01 , i think this is due to async exception getting installed but not handled immediately for the test case. as frequency_counter_overflow_inner and profile_method are prominent code path. I go for next fix. so trying webrev.02. http://cr.openjdk.java.net/~jcm/8246381/webrev.02/
15-07-2020

The proposed fix is fine as far as it goes. I'm just saying there may be more to examine here for those other issues. The build_interpreter_method_data code takes a lock which means the thread can block, which means it can safepoint/handshake, which _might_ mean it can install an async exception. I'm trying to check on the details of that, but identifying the paths where we can potentially install async exceptions is non-trivial to work out.
15-07-2020

Intention of current fix is to avoid crashes in production build. not to handle all cases. crash issue is observed only with "do not unlock" flag handling and the methods are frequency_counter_overflow_inner and profile_method. I am planning for extensive fix in https://bugs.openjdk.java.net/browse/JDK-8249451 which will handle all clearing code that is in c1, interpreter and deopt.
15-07-2020

but it was said that in that code path there will be no Java method execution except it can have OOM condition(Xcomp and bootstrap JVMCI cases excluded). If there is no Java method execution then there is less chances of getting any async installed right? all these code clearing part will be handled separately in the bug https://bugs.openjdk.java.net/browse/JDK-8249451
15-07-2020

This assertion is now redundant with the explicit check on entry: 1047 assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending"); Looking at this code: 1101 Method::build_interpreter_method_data(method, THREAD); 1102 if (HAS_PENDING_EXCEPTION) { 1103 assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); 1104 CLEAR_PENDING_EXCEPTION; and looking at the implementation of Method::build_interpreter_method_data, it is not at all clear to me that we won't hit a point where we can install a pending async exception.
15-07-2020

Plan is to do an interim fix for jdk15 as async handling on this path(unsafe/Thread.stop) can produce crashes of various forms. This fix will remove all kind of crashes http://cr.openjdk.java.net/~jcm/8246381/webrev.01/ There are some more problems to be handled, like some exception clearing logics that is there in compiler/deoptimization, that will be addressed separately by https://bugs.openjdk.java.net/browse/JDK-8249451
15-07-2020

https://github.com/openjdk/jdk/blob/master/src/hotspot/share/runtime/deoptimization.cpp too clears exceptions in similar fashion.
03-07-2020

had another check _thread_blocked_trans doesn't check for asyncs.. so removing the comment.
02-07-2020

It is in InterpreterMacroAssembler, this will happen for both (async and sync). In JVMTI spec there was no explicit mention about how and when to deal exception condition when JVMTI Popframe, early return condition is set. so i believe whatever that is there is correct.
25-06-2020

Sorry I don't follow. That link takes to me to code that is part of call_VM, which is after the call, and we have empty definitions: void MacroAssembler::check_and_handle_earlyret(Register java_thread) { } void MacroAssembler::check_and_handle_popframe(Register java_thread) { } so we would then proceed to the normal exception check.
25-06-2020

JDK-8246727 case occurred as it was not immediately forwarded to it exception handler after pending_exception being set. This could happen only for PopFrame and EarlyReturn case[1]. //If we check for pending exceptions on entry to frequency_counter_overflow then we will avoid the problem reported// Yes. [1] https://github.com/openjdk/jdk/blob/1550fd889b467d9866ac00a3bc7ab1f879e7f20a/src/hotspot/cpu/x86/macroAssembler_x86.cpp#L1561
24-06-2020

//If there is actually no possibility of executing Java code from this context then it would be good if there were a way to capture that somehow.// proposed solution of checking for InternalError and ThreadDeath for all clearing code make more sense here. //But we would still need the initial assertion that there are no pending exceptions to be replaced by a check for a pending exception and immediate return.// Ok. So i think if this is fixed, async handling part is fixed except for PopFrame, and EarlyReturn(which will be handled separately by JDK-8246727)
24-06-2020

I'm not at all clear on the details of the PopFrame/EarlyReturn part of the problem. If we check for pending exceptions on entry to frequency_counter_overflow then we will avoid the problem reported in JDK-8246727.
24-06-2020

> But what if the compiler is JVMCI/Graal? Could that lead to Java code execution related to the compiler itself? Compilers normally run in compiler threads, the policy call backs (which run in user threads) just queue up the requests.
23-06-2020

> one other question i have is jvmti StopThread specification doesn't say it is always instance of ThreadDeath ? can it be instance of any throwable class ? It can but it is a rarely used debugging facility and I don't think we should reasonably be expected to support that in this kind of situation. > from this observation i think suggested fix JRT_ENTRY_NO_ASYNC is correct. If there is actually no possibility of executing Java code from this context then it would be good if there were a way to capture that somehow. But what if the compiler is JVMCI/Graal? Could that lead to Java code execution related to the compiler itself? But we would still need the initial assertion that there are no pending exceptions to be replaced by a check for a pending exception and immediate return.
23-06-2020

Method::load_signature_classes(method, CHECK_AND_CLEAR_NULL); => wouldn't execute as method signature is already resolved. ConstantPool::resolve_string_constants(CHECK_AND_CLEAR_NULL); => wouldn't execute any java code, can have OOM condition. so nothing to worry Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR); => wouldn't execute any java code, can have OOM condition. so nothing to worry from this observation i think suggested fix JRT_ENTRY_NO_ASYNC is correct.
23-06-2020

yes there are other places. one other question i have is jvmti StopThread specification doesn't say it is always instance of ThreadDeath ? can it be instance of any throwable class ?
23-06-2020

Ok, i will investigate this.
23-06-2020

I'm not clear exactly what Java code ends up being executed via either InterpreterRuntime::frequency_counter_overflow_inner or InterpreterRuntime::profile_method, but on reflection I don't see why this code should be treated specially when it comes to async exceptions. There is no async exception deferral mechanism when executing Java code. And as far as I can see the only problem the exception would cause relates to the assertion after the call that there is no exception - an assertion that I think should not be there, but the code may need to react to the presence of an exception.
23-06-2020

//That is incorrect behaviour for async exceptions - the compiler code must not lose async exceptions. // Ok i mistakenly thought it needn't if I handle everything that is outside of CompilationPolicy::event. Unsafe access can come only from outside, Thread.Stop is the only that can come from inside but can get cleared. i thought ignoring Thread.Stop inside CompilationPolicy::event java code execution is fine. but from your comment it doesn't seems so. so in that case we should have separate mechanism to defer all async exceptions inside InterpreterRuntime::frequency_counter_overflow_inner and InterpreterRuntime::profile_method On later thought i understand even unsafe access can come from inside CompilationPolicy::event java code execution (as it involve class loading)
23-06-2020

Yes I think so. Unfortunately that means checking for ThreadDeath (or subclass thereof) for Thread.stop and InternalError for unsafe-memory-access. I suspect there may be other places in the JIT code where we swallow all exceptions.
23-06-2020

Probably we should clear specific exception that can be thrown by these methods[1] and propagate all other exception back to the caller. instead of current arrangement [1] if (comp->is_c2()) { method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL); // Resolve all classes seen in the signature of the method // we are compiling. Method::load_signature_classes(method, CHECK_AND_CLEAR_NULL); }
23-06-2020

[~jcm] If left to runtime then I will change the JRT_ENTRY to JRT_ENTRY_NO_ASYNC - but that only fixes one part. > java codes in CompilationPolicy::event clears all exceptions(async or not), That is incorrect behaviour for async exceptions - the compiler code must not lose async exceptions. So it will have to detect and defer/preserve them. Though I actually can't see how it can possibly do that.
22-06-2020

removing both comments.. native calls always goes through native wrappers with exception checks. and we have no case for a floating pending_exception in compiler.
22-06-2020

I instrumented the code to add BEFORE SUSPEND and AFTER SUSPEND in exception log // Check for pending external suspend. if (is_external_suspend_with_lock()) { // exception log BEFORE SUSPEND frame_anchor()->make_walkable(this); java_suspend_self_with_safepoint_check(); // exception log AFTER SUSPEND } log output [1], we can clearly see all events happen in between two log out BEFORE SUSPEND and AFTER SUSPEND . so the extra Safepoint check that is added after self_suspend throws exception in this case, but some cases exception is thrown later. but in all failing cases i assume pending async exception get installed when we are in this code block [ BEFORE SUPEND- AFTER SUSPEND] [1] =============================================================== - cm03t001.cpp, 653: Checking positive: PopFrame [0.371s][info ][exceptions] BEFORE SUSPEND [0.371s][debug ][safepoint ] Safepoint synchronization initiated using futex wait barrier. (12 threads) [0.371s][info ][safepoint ] Safepoint "ThreadSuspend", Time since last: 32332922 ns, Reaching safepoint: 119265 ns, At safepoint: 9738 ns, Total: 129003 ns [0.371s][trace ][jvmti ] [JVMTI agent thread] PopFrame { thread=Debuggee Thread [0.371s][debug ][safepoint ] Safepoint synchronization initiated using futex wait barrier. (12 threads) [0.371s][info ][safepoint ] Safepoint "UpdateForPopTopFrame", Time since last: 295277 ns, Reaching safepoint: 114926 ns, At safepoint: 17543 ns, Total: 132469 ns [0.371s][trace ][jvmti ] [JVMTI agent thread] PopFrame } - cm03t001.cpp, 693: Checking positive: InterruptThread - cm03t001.cpp, 697: Checking positive: StopThread [0.372s][info ][exceptions] Pending Async. exception installed of type: java.lang.ThreadDeath [0.372s][info ][exceptions] Async. exception installed at runtime exit (0x00007f419c03d760) (pc: 0x00007f41e0d47993 sp: 0x00007f41dc4c9860 ) of type: java.lang.ThreadDeath ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ instrumented code to get backtrace at pending_exception set "Executing ps" for thread: "Debuggee Thread" #14 prio=5 os_prio=0 cpu=31.78ms elapsed=0.06s tid=0x00007f419c03d760 nid=0x41a5 runnable [0x00007f41dc4c9000] java.lang.Thread.State: RUNNABLE Thread: 0x00007f419c03d760 [0x41a5] State: _running _at_poll_safepoint 0 JavaThread state: _thread_in_Java 1 - frame( sp=0x00007f41dc4c9860, unextended_sp=0x00007f41dc4c9860, fp=0x00007f41dc4c98a8, pc=0x00007f41e0d47993) nsk.jvmti.scenarios.capability.CM03.cm03t001Thread.waitUntilQuit(cm03t001.java:143) [0.372s][info ][handshake ] Handshake "InstallAsyncException", Targeted threads: 1, Executed by targeted threads: 1, Total completion time: 175280 ns 2 - frame( sp=0x00007f41dc4c98b8, unextended_sp=0x00007f41dc4c98c8, fp=0x00007f41dc4c9918, pc=0x00007f41e0d2a7cc) nsk.jvmti.scenarios.capability.CM03.cm03t001Thread.delay(cm03t001.java:138) 3 - frame( sp=0x00007f41dc4c9928, unextended_sp=0x00007f41dc4c9928, fp=0x00007f41dc4c9978, pc=0x00007f41e0d2a7cc) nsk.jvmti.scenarios.capability.CM03.cm03t001Thread.run(cm03t001.java:124) ThreadState(thread='MainThread', state='debuggeeWaiting') waiting for state debuggeeThreadDeath [0x00007f41f4c3ac92] JavaThread::check_and_handle_async_exceptions(bool)+0x252 [0x00007f41f4c3b54d] JavaThread::handle_special_runtime_exit_condition(bool)+0x2dd [0x00007f41f41827f2] HandshakeState::process_self_inner()+0x3d2 [0x00007f41f4a8f8ad] SafepointMechanism::block_if_requested_slow(JavaThread*)+0xcd ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [0.374s][info ][exceptions] AFTER SUSPEND
22-06-2020

java codes in CompilationPolicy::event clears all exceptions(async or not), so it is not desirable to leave it to any code that is executing inside CompilationPolicy::event. so either we should return if there is async exception or save and restore.
22-06-2020

Yes both are non related issues. for JDK-8246381 only thing JRT_ENTRY_NO_ASYNC does is, it doesn't check for async exception condition at ~JavaToVM. there can be many transition inside CompilationPolicy::event(when it execute java code) that handles async and clears it later. so my proposal was either to save and restore exception OR return at frequency_counter_overflow_inner entry if there is an exception condition( JRT exit will set pending exception and callVM exit will forward it(if there is no PopFrame, or early return)). On JDK-8246727, will run agent in verbose mode and get the log.
22-06-2020

I'm trying to follow along here but it is quite complex. If I understand things correctly then we have two apparent bugs in relation to this issue and JDK-8246727. With regard to the current issue the problem is not in IRT::frequency_counter_overflow, which properly saves and restores the do_not_unlock flag when calling Java code, but with the async exception check in the ThreadInVMfromJava destructor, which is part of the JRT_ENTRY. That code path does not deal with the do_not_unlock flag and so leads to a later failure when the unlock is attempted inappropriately. I still feel a solution to this particular issue would be to use JRT_ENTRY_NO_ASYNC. With regard to JDK-8246727 the problem is that we can actually enter this entire method entry logic with a pending exception, and the assertion in frequency_counter_overflow is the first to catch that. I can't quite follow all the details of exactly when/where the pending async exception gets installed so can't really comment on where the actual bug lies. It does seem wrong to make forward progress with an exception pending, but I don't know exactly where we should have further checks that would prevent that.
22-06-2020

verified the case for JDK-8246727[1] . pending exception is set at backward branch in method 'waitUntilQuit', on call_VM_base exit before we check for exception and forward it. pop frame is checked and frame is popped, "waitUntilQuit" method is re-executed. on entry frequency_counter_overflow detect exception is set and fail. see log [1] log[1] details: Symbol: 'nsk/jvmti/scenarios/capability/CM03/cm03t001Thread' count 5Symbol: 'waitUntilQuit' count 2Symbol: '()V' count 65535 is printed in method exit for verifying purpose. first stack trace is at. pending exception set (at backward branch) then method exit second stack trace for assert failure, which is method entry for waitUntilQuit
22-06-2020

The transitions within the Java code called through CompilationPolicy::event are not a problem in terms of interaction with the do_not_unlock flag. Once the async exception starts propagating in Java code it is no longer an async exception just an exception. The problem is the detection of the async exception in the ~JavaToVM outside the protection of the do_not_unlock flag. Now the assertion after CompilationPolicy::event that expects no pending exception will fire if the Java code did in fact get any exception (async or not) and I think that assertion may be misguided - unless CompilationPolicy::event explicitly clears any exception and stops it from propagating. But in any case this seems a separate problem.
22-06-2020

//yet to check why both PopFrame and async condition co-existed// suspend-thread state is safe state. and any number of safepoint operation can execute one after the other there. with TLH threadstop and JDK-8221207 (extra safepoint check after suspend-resume) chances of this getting noticed became higher for the test case.
21-06-2020

on exception condition we needn't service the callVM request for frequencey_overflow check and handle. so i guess even returning after having async exception condition then and there at frequency_counter_overflow_inner entry will do. for Pop frame case it seems like pending exception is set and is not immediately forwarded. for this we should disable async exception condition check if pop frame is requested and pop frame should return error if async exception condition exist. (yet to check why both PopFrame and async condition co-existed) presently async exception condition check are done only at ~JavaToVM, ~JavaToNative and at some safepoints. and check in JavaCallWrapper is just for asserts. May be we require more async exception condition checks and handling or remove handling in JavaWrapper and assume ~JavaToVM,~JavaToNative and other SP handling would suffice our case.
21-06-2020

loading, resolutions in CompilationPolicy::event doesn't propagate exceptions and execute java code, we have no control there. so restricting it at frequency_counter_overflow and profile_method is not enough i guess. we need to save and restore to make work properly. On JDK-8246727. my assumption is exception is set properly, due to pop frame the exception is not handled immediately at call_VM_base exit. and it reaches InterpreterRuntime::frequency_counter_overflow for the next iteration and fail (need to verify this).
19-06-2020

Also see JDK-8246727 which fails in a slightly different way due to async exceptions. I'm unclear how the async exception gets installed prior to calling InterpreterRuntime::frequency_counter_overflow.
19-06-2020

Perhaps we just need to use JRT_ENTRY_NO_ASYNC for frequency_counter_overflow and profile_method?
19-06-2020

Thanks for the additional information. The problem is specific to this kind of async exception because, as you note we have to execute Java code to create the InternalError to be thrown. For regular Thread.stop related async exceptions that exception object already exists and "throwing" it doesn't involve any Java code execution. I need to study all these details more closely. As safepoints become fewer and fewer, the locations where we detect pending async exceptions is also becoming fewer, which means the non-safepoint related checks are more likely to come into play.
19-06-2020

In short what we are seeing in the test case ================================================= in InterpreterRuntime::frequency_counter_overflow_inner we save and restore // use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized // flag, in case this method triggers classloading which will call into Java. UnlockFlagSaver fs(thread); https://github.com/openjdk/jdk/blob/a16994ff7b321af20f49a56e11f458e052133568/src/hots ~JavatoVM doesn't do that(flag save, restore) and we have this throw new Exceptions, new Exceptions creation execute java code resetting the flag. In exception handling path unwind find it in reset state and fail. we clear all exception propagation in CompilationPolicy::event, still this can happen(throwing async exception) CompilationPolicy::event code path too, where we allow to execute java code. So my fix for this block special case is to extract async exception at start of the block. save and restore it* and handle in the immediate to Java exit. same fix should be applied in other places where we save and restore UnlockFlagSaver flag(and is a callVM) PS: fix also involves save and restoring of UnlockFlagSaver in JavaThread::check_and_handle_async_exceptions *(clear it for CompilationPolicy::event is implied) ======================================================= JavaCallWrapper case is not very clear for me. i see pending exception not expected checks in other places(i.e. call_stub). and there is no immediate handling!! so doubting should we really handle async exception there. isn't other places where immediate handling is available suffice for our purposes ?
19-06-2020

I'd still like to understand how/why the monitor BasicObjectLock stack entries appear to get messed up.
19-06-2020

JavaCallWrapper handling requires more investigation.
17-06-2020

so just like do_not_unlock_if_synchronized is saved and restored in InterpreterRuntime::frequency_counter_overflow_inner. save and restore the exception. clear it for the CompilationPolicy::event call. handle it in JRT exit(i.e. throw the exception in JRT exit).
16-06-2020

after having another look at JDK-7131259 , i feel it is bad idea to handle async exception in frequency counter overflow code block. may be we should disable async exception handling for this code area. save and restore the async exception for handling it outside the block.
16-06-2020

some history on other asserts that exist in InterpreterRuntime::frequency_counter_overflow_inner https://bugs.openjdk.java.net/browse/JDK-7131259 may be those asserts should be relaxed for async exceptions!
16-06-2020

call_VM is with exception check and forward exception ON. backtrace below [1] exception is thrown at JRT exit =>> InterpreterRuntime::frequency_counter_overflow_inner [1] ====================================================== #1 0x00007ffff643ee3b in MacroAssembler::call_VM_base (<InterpreterRuntime::frequency_counter_overflow(JavaThread*, unsigned char*)>, number_of_arguments=1, check_exceptions=true) at /scratch/8238996/jdk/open/src/hotspot/cpu/x86/macroAssembler_x86.cpp:1576 #2 0x00007ffff60c244b in InterpreterMacroAssembler::call_VM_base (<InterpreterRuntime::frequency_counter_overflow(JavaThread*, unsigned char*)>, number_of_arguments=1, check_exceptions=true) at /scratch/8238996/jdk/open/src/hotspot/cpu/x86/interp_masm_x86.cpp:309 #3 0x00007ffff643efac in MacroAssembler::call_VM_helper (<InterpreterRuntime::frequency_counter_overflow(JavaThread*, unsigned char*)>", number_of_arguments=1, check_exceptions=true) at /scratch/8238996/jdk/open/src/hotspot/cpu/x86/macroAssembler_x86.cpp:1607 #4 0x00007ffff643df74 in MacroAssembler::call_VM (<InterpreterRuntime::frequency_counter_overflow(JavaThread*, unsigned char*)>, arg_1=0x6, check_exceptions=true) =====================================================
16-06-2020

The async exception check is not happening when I thought it was - I thought we were in the JavaCallWrapper. Howqever it is not at all clear to me what happens after: call_VM =>> InterpreterRuntime::frequency_counter_overflow with regards to the pending exception that is now present. I can't spot the code that says "hey we have an exception pending and should start stack unwinding". If that code is not present then we continue to attempt to lock the object monitor while we have the pending exception. And that code seems fine. When we eventually realize we have to abort the method call due to the pending exception we will perform the monitor exit as part of removing the activation. That is where the assertion is failing. But I can't see anything that is obviously wrong in the interpreter code in this regard.
16-06-2020

Source code location ===================================== JavaThread::check_and_handle_async_exceptions (this=0x7ffff0033ab0, check_unsafe_error=true) at /scratch/8238996/jdk/open/src/hotspot/share/runtime/thread.cpp:2349 #1 0x00007ffff6789752 in JavaThread::handle_special_runtime_exit_condition (this=0x7ffff0033ab0, check_asyncs=true) at /scratch/8238996/jdk/open/src/hotspot/share/runtime/thread.cpp:2386 #2 0x00007ffff5cbcb75 in ThreadInVMfromJava::~ThreadInVMfromJava (this=0x7ffff7f7f630, __in_chrg=<optimized out>) at /scratch/8238996/jdk/open/src/hotspot/share/runtime/interfaceSupport.inline.hpp:178 #3 0x00007ffff60d26f3 in InterpreterRuntime::frequency_counter_overflow_inner (thread=0x7ffff0033ab0, branch_bcp=0x0) at /scratch/8238996/jdk/open/src/hotspot/share/interpreter/interpreterRuntime.cpp:1050 #4 0x00007ffff60d2062 in InterpreterRuntime::frequency_counter_overflow (thread=0x7ffff0033ab0, branch_bcp=0x0) at /scratch/8238996/jdk/open/src/hotspot/share/interpreter/interpreterRuntime.cpp:1011 ================================================== generated location ================================================== MacroAssembler::call_VM =>> InterpreterRuntime::frequency_counter_overflow at /scratch/8238996/jdk/open/src/hotspot/cpu/x86/macroAssembler_x86.cpp:1344 TemplateInterpreterGenerator::generate_counter_overflow at /scratch/8238996/jdk/open/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp:483 TemplateInterpreterGenerator::generate_normal_entry at /scratch/8238996/jdk/open/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp:1488 TemplateInterpreterGenerator::generate_method_entry at /scratch/8238996/jdk/open/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp:482 in TemplateInterpreterGenerator::generate_all (this=0x7ffff7f7fa50) ===================================================== so it happens with all compilers, not JVMCI compiler specific.
15-06-2020

The do_not_unlock_if_synchronized flag is used to guard the stackoverflow check on monitor entry so that if we get the StackOverflowError the logic that unwinds the stack will skip attempting to unlock the monitor as it had not been locked yet. If the pending async exception is being found at the start of the call, before the monitor has actually been acquired, but after we have entered the monitor acquisition logic, then yes it will be necessary to also skip the unlock - perhaps by using the flag. However it is not at all clear to me exactly when the async exception is detected in relation to the monitor acquisition code. If this only fails with JVMCI/Graal then the issue would seem to be in the JVMCI/Graal monitor acquisition code.
15-06-2020

when analyzing method entry i see we have the feature to support exception handling before lock creation and after it. for it we set a flag do_not_unlock_if_synchronized, the problem with async handling is, it doesn't save and restore this flag. it works fine on saving and restoring this flag.
13-06-2020

About the issue: method entry for getWhiteBox api on somepaths doesn't have the locks setup when it checks for async exception. when it unwinds it doesn't find the expected lock slot. i think this issue should be fixed at method entry? like to disable async exception checks in more places ?
12-06-2020

bulk access aync exception was not designed to be caught just after its exit. it was leaf call without SP, and so i added WB forcesafepoint just to ensure it is detected thrown for test purpose. i see this should be issue with non-bulk access as well, i can reproduce it there as well. i feel something wrong with exception management. and trying to dig it further.
12-06-2020

IIRC we fairly recently made changes that removed some safepoint/handshake polling points (on backward branches) and that is probably what results in the async unsafe access error only getting detected on the call to getWhiteBox() rather than earlier whilst still in the context of the test method.
11-06-2020

on first look there seems to be some issue with async exception thrown at method entry and its handling. will have a detailed check on this.
11-06-2020

By pure coincidence I am investigating this same test failing at the monitorexit for getWhiteBox(). My initial investigations suggest that this may be a problem with how we detect async unsafe access errors, as it appears to be thrown from the call to getWhiteBox() instead of during the test() method. This seems to be because we only detect async exceptions at a very few locations.
11-06-2020

yes sure [~iveresov]
11-06-2020

[~jcm], since you're one of the authors JDK-8191278 and hopefully remember how it all supposed to work, can you please take a look at this one? It's generic, to reproduce, build a fastdebug or slowdebug jdk and run (set $JAVA_HOME to the JDK you've just built): #jtreg -va -jdk:$JAVA_HOME -vmoptions:"-XX:CompileThresholdScaling=0.1" -dir:open/test/hotspot/jtreg runtime/Unsafe/InternalErrorTest.java
11-06-2020

shouldn't this be an issue for non-bulk access as well ?
11-06-2020

Thank you very much for the input, David. very much likely that is the case, will verify it.
11-06-2020

I tried this test with the current version and it crashes as well, although at a different place (when walking the stack during a GC), I attached the hs_err.
04-06-2020

[~iveresov] please, check with latest Graal as David suggested.
03-06-2020

To reproduce the failure do run the test: > jtreg -va -jdk:jdk/15/b24/fastdebug -vmoptions:"-server -ea -esa -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler -Djvmci.Compiler=graal -XX:+TieredCompilation -XX:CompileThresholdScaling=0.1" -dir:open/test/hotspot/jtreg runtime/Unsafe/InternalErrorTest.java
02-06-2020