Repository navigation
CefBrowserApiDebugSafeTest deterministically crashes the process (mojo interface_endpoint_client.cc:538 DCHECK) in the Debug/coverage build #27
Description
Activity
Status update, not closing -- currently not reproducing, root cause not found.
Initial suspicion was that this was actually the same bug as #31 (a
CefClient.onGotFocus()infinite-recursion StackOverflowError, since this issue's own description -- "severalException in thread AWT-EventQueue-0with no visible stack trace" -- matches that bug's signature exactly). Tested directly: rebuilt theENABLE_COVERAGEDebug build fresh and ranCefBrowserApiDebugSafeTest3x in isolation and once in a 6-class combined run (matching both repro conditions this issue describes) -- passes cleanly every time. Then re-tested withCefClient.javareverted to its pre-#31-fix state specifically, to isolate whether #31's fix was responsible: also passes cleanly 3/3, refuting that hypothesis directly.So this currently doesn't reproduce at all, with or without #31's fix, under either of this issue's own stated repro conditions. Possibly stale (fixed by something else, unrelated to #31, in the time since this was filed), possibly environment/timing-dependent and just didn't fire today. Leaving open since root cause is still unconfirmed either way -- if this resurfaces, the mojo
interface_endpoint_client.cc:538DCHECK signature is the thing to chase directly next time, not the AWT-EventQueue-0 storm (that's #31's, now fixed, and evidently a red herring here).Root-caused, via the sibling class
CefBrowserApiTest(sameinterface_endpoint_client.cc:538 DCHECK failed: !has_pending_responders()signature). Used the jpype gdb technique (handle SIGSEGV nostop noprint pass, launch-under-gdb) to catch it live and get a real backtrace:N_Close(force=true) [native/CefBrowser_N.cpp:1515] -> CefBrowserHostCToCpp::CloseBrowser(true) -> AlloyBrowserHostImpl::CloseContents() -> RenderProcessHostImpl::FastShutdownIfPossible() -> FastShutdown() -> RenderProcessHostImpl::ProcessDied() -> SiteInstanceGroup::RenderProcessExited() -> RenderFrameHostImpl::RenderProcessGone() -> RenderFrameDeleted() -> WebContentsImpl::RenderFrameDeleted() -> CefBrowserContentsDelegate::RenderFrameDeleted() -> CefBrowserInfo::RemoveFrame() -> CefFrameHostImpl::Detach() -> DetachRenderFrame() -> mojo::Remote<RenderFrame>::ResetWithReason() -> InterfaceEndpointClient::CloseWithReason() -> PassHandle() [DCHECK fires here]FastShutdown()kills the renderer process without waiting for in-flight IPC to settle. If a mojo call to the renderer (in this case,browser.find()/browser.viewSource()) still has a pending responder when the browser is force-closed right after,PassHandle()'s!has_pending_responders()DCHECK fires -- compiled out in Release, live in Debug/coverage builds, hence why this never showed up outsideENABLE_COVERAGE.Underlying gap: JCEF has no
CefFindHandlerbinding at all (noonFindResult), so there's no way for Java code to actually wait forfind()'s async completion before closing -- unlike CEF's ownfind_handler_unittest.cc(~/devel/cef/tests/ceftests/), which always waits forOnFindResult'sfinalUpdatebefore callingStopFinding()+closing. That's the real, complete fix (a newfind_handler.cpp/CefFindHandlerJava interface) but is its own scoped feature addition, not a quick fix here.Mitigation applied (
CefBrowserApiTest.java, commit follows): give the CEF UI thread's message pump ~300ms to drain the pending response before closing. Verified 5/5 clean isolated runs plus the 6-class batch (includingCefBrowserApiDebugSafeTest) clean underENABLE_COVERAGE. Same fix class as#4/#23's finalizer-guard work (c8df5fc) and matches the general pattern in this codebase: shutdown proceeding without draining a pending in-flight op.Given this class isn't currently reproducing per the last comment, no change needed here -- but if it resurfaces, apply the same settle-before-close mitigation (or better, wait on a real
CefFindHandler/request-completion signal once that binding exists) rather than re-investigating from scratch.Related: #32 (JCEF had no CefFindHandler binding) is now fixed in 135dc98. `CefBrowserApiTest` (the sibling class hitting the identical DCHECK signature, root-caused in 0d5890b) now waits on the real `onFindResult(finalUpdate=true)` before closing instead of a blind settle delay -- worth trying against `CefBrowserApiDebugSafeTest`'s two methods here if they also call `find()`/`viewSource()` before closing.
🤖 Generated with Claude Code
Confirmed fixed via a real run (the thing this issue was still waiting on).
CefBrowserApiDebugSafeTestwas already un-@Disabledfrom the shared-browser (Tier 1) harness migration, which fixed a cold-start hazard -- a different mechanism fromCefBrowserApiTest's settle-period/onFindResultmitigation discussed above, and not needed here.3/3 clean isolated runs (
--select-class tests.junittests.CefBrowserApiDebugSafeTest, exit 0, no DCHECK/abort) plus a clean batched run alongsideCefBrowserApiTestandCefDisplayHandlerTest(6/6 tests passing, exit 0).Details:
plan/tasks/20260903-11-issue27-browserapidebugsafe-mojo-dcheck.md(archived).🤖 Generated with Claude Code
Summary
java/tests/junittests/CefBrowserApiDebugSafeTest.java(two tests:executeJavaScriptAndLoadRequestDoNotThrow,createScreenshotReturnsARealImage)deterministically crashes the whole JUnit process before any
@Testmethodeven starts, when run against the
ENABLE_COVERAGE/coverage-instrumentedDebug build -- reproduces both in isolation and as part of a small
multi-class run.
preceded by several
Exception in thread "AWT-EventQueue-0"with no visiblestack trace.
Not root-caused. Currently
@Disabledper this project's standing strategy(disable flaky/broken ported tests rather than chase the underlying native
crash inline).
Reproduction
Run
CefBrowserApiDebugSafeTestalone (or as part of a small 6-class--select-classrun alongside 5 other independently-reliable classes)against a coverage-instrumented Debug build.
Impact
browser.loadRequest(),browser.executeJavaScript()+ real request-objectloading, and
browser.createScreenshot()all lose their only existing testcoverage while this stays disabled.