JDK-8189420 : Crash in :web:test in debug build
  • Type: Bug
  • Component: javafx
  • Sub-Component: web
  • Affected Version: 8u141,9,10
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2017-10-17
  • Updated: 2017-12-18
  • Resolved: 2017-10-23
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 10 JDK 8
10Fixed 8u171Fixed
ASSERTION FAILED: exec->vm().currentThreadIsHoldingAPILock() 
/home/murali/Apr_CPU/rt/modules/javafx.web/src/main/native/Source/JavaScriptCore/API/APICast.h(132) : const OpaqueJSValue* toRef(JSC::ExecState*, JSC::JSValue) 
1 0x7fc21e7c6933 WTFCrash 
2 0x7fc21c1f30e9 
3 0x7fc21d373639 
4 0x7fc21d3736b6 Java_com_sun_webkit_dom_JSObject_evalImpl 
5 0x7fc289b60d35 
# A fatal error has been detected by the Java Runtime Environment: 
# SIGSEGV (0xb) at pc=0x00007fc21e7c6938, pid=5660, tid=5695 
# JRE version: Java(TM) SE Runtime Environment (9.0+180) (build 9+180) 
# Java VM: Java HotSpot(TM) 64-Bit Server VM (9+180, mixed mode, tiered, compressed oops, g1 gc, linux-amd64) 
# Problematic frame: 
# C [libjfxwebkit.so+0x2daa938] WTFCrash+0x23 
Changeset: 3dd0f57a7564 Author: mbilla Date: 2017-10-23 12:43 +0530 URL: http://hg.openjdk.java.net/openjfx/10-dev/rt/rev/3dd0f57a7564


> Here m_apiLock (of type "JSLock") is implemented as smart pointer RefPtr Thanks, that's what I was looking for. This looks fine to me. +1

Webrev (includes fixing both places) : http://cr.openjdk.java.net/~mbilla/8189420/webrev.02/ 1. Regarding when the lock will be released : Here m_apiLock (of type "JSLock") is implemented as smart pointer RefPtr [1] RefPtr<JSLock> m_apiLock; JSLock& apiLock() { return *m_apiLock; } So when the JSLockHolder object goes out of scope and destructor of JSLockHolder gets called, apiLock->unlock(); will be called and based on ref. count, willReleaseLock(); will be called. JSLockHolder::~JSLockHolder() { RefPtr<JSLock> apiLock(&m_vm->apiLock()); m_vm = nullptr; apiLock->unlock(); } [1] https://webkit.org/blog/5381/refptr-basics/

1. That answers the "how" but not the "when" the lock is released. In other words, you added a call to lock, but I see no corresponding call to unlock. Does the implementation use smart pointers or some other mechanism to ensure that unlock is called when the object goes out of scope / is dereferenced? 2. I recommend fixing both places.

[~kcr] 1. How/when is the lock released? --> Here lock is implemented as as Ref counted lock (m_lockCount) in JSLock.cpp. Please find below code for lock and unlock API's. void JSLock::lock(intptr_t lockCount) { ASSERT(lockCount > 0); if (currentThreadIsHoldingLock()) { m_lockCount += lockCount; return; } if (!m_hasExclusiveThread) { m_lock.lock(); m_ownerThreadID = std::this_thread::get_id(); } ASSERT(!m_lockCount); m_lockCount = lockCount; didAcquireLock(); } void JSLock::unlock(intptr_t unlockCount) { RELEASE_ASSERT(currentThreadIsHoldingLock()); ASSERT(m_lockCount >= unlockCount); // Maintain m_lockCount while calling willReleaseLock() so that its callees know that // they still have the lock. if (unlockCount == m_lockCount) willReleaseLock(); m_lockCount -= unlockCount; if (!m_lockCount) { if (!m_hasExclusiveThread) { m_ownerThreadID = std::thread::id(); m_lock.unlock(); } } } 2. There is another API (Java_com_sun_webkit_dom_JSObject_toStringImpl) where lock is missing in BridgeUtils.cpp. But since i did not come across any issue (OR use case) in this case, i didn't corrected for this API. Based on your opinion, i can correct/leave for this API. JNIEXPORT jstring JNICALL Java_com_sun_webkit_dom_JSObject_toStringImpl (JNIEnv *env, jclass, jlong peer, jint peer_type) { JSObjectRef object; JSContextRef ctx; checkJSPeer(peer, peer_type, object, ctx); JSC::ExecState* exec = toJS(ctx); return toJS(object)->toString(exec)->value(exec) .toJavaString(env).releaseLocal(); }

Two questions: 1. How/when is the lock released? 2. Are there other places where there is a missing lock?

webrev: http://cr.openjdk.java.net/~mbilla/8189420/webrev.01/ Verified the fix in 10 and :web:test PASSED