JVM crashes on macOS when entering too many nested event loops
Christopher Schnick
crschnick at xpipe.io
Wed Mar 12 08:15:53 UTC 2025
Thank you for your effort on that investigation. Hopefully this issue
can be fixed somehow. For now, we tweaked some calls to runLater and
enterNestedEventLoop to be called a little bit less often.
On 11/03/2025 20:40, Martin Fox wrote:
> I entered a bug https://bugs.openjdk.org/browse/JDK-8351733.
>
> This crash doesn’t happen if you create nested event loops while
> processing events. I wrote a test app that started a new event loop on
> every mouse click and easily created over 400 nested loops. So we’re
> not pushing up against the native thread stack size limit, we’re
> running into an undocumented limit on the number of nested
> CFRunLoopRun calls. There’s a line to that effect in the crash log
> (which I overlooked for a while because I’m not used to crash logs
> being that helpful).
>
> The bug is specific to the way the Mac handles runLater blocks and
> other internal uses of performSelectorOnMainThread. So far I can only
> reproduce this using Platform::runLater e.g. block A schedules
> runLater block B and then enters a nested event loop, block B
> schedules runLater block C and enters a nested event loop, and on and
> on. In a real app it’s also possible that some internal uses of
> performSelectorOnMainThread might be interacting with
> Platform::runLater calls in unexpected ways.
>
> As far as I know here’s no way to ask the system what the CFRunLoopRun
> nesting limit is and no way to detect at runtime when we’ve hit it.
> The best we can do is maintain an internal counter and throw a runtime
> exception when it hits, say, 245 nested CFRunLoopRun calls. That at
> least would produce a very long but usable Java stack trace.
>
> I could update Platform::canStartNestedEventLoop to detect this case
> but I’m not sure it would be useful. When you hit this condition the
> system will already be 240+ loops in and they will all have to be
> unwound to get the system back into a usable state.
>
> Adding the code to glass that throws an exception and writing up a
> manual test case is easy. Writing up an automated test case is much
> harder (at least for me).
>
>> On Mar 10, 2025, at 7:47 PM, Christopher Schnick <crschnick at xpipe.io>
>> wrote:
>>
>> Our code and some libraries do enter some nested event loops at a few
>> places when it makes sense, but we didn't do anything to explicitly
>> provoke this, this occurred naturally in our application. So it would
>> be nice if JavaFX could somehow guard against this, especially since
>> crashing the JVM is probably the worst thing that can happen.
>>
>> I looked at the documentation, but it seems like the public API at
>> Platform::enterNestedEventLoop does not mention this.
>> From my understanding, the method Platform::canStartNestedEventLoop
>> is potentially the right method to indicate to the caller that the
>> limit is close by returning false.
>> And even if something like an exception is thrown when a nested event
>> loop is started while it is close to the limit, that would still be
>> much better than a direct crash.
>>
>> Best
>> Christopher Schnick
>>
>> On 10/03/2025 18:51, Andy Goryachev wrote:
>>> This looks to me like it might be hitting the (native) thread stack
>>> size limit.
>>> c.s.glass.ui.Application::enterNestedEventLoop() even warns about it:
>>> * An application may enter several nested loops recursively. There's no
>>> * limit of recursion other than that imposed by the native stack size.
>>> -andy
>>>
>>> *From:*openjfx-dev<openjfx-dev-retn at openjdk.org>on behalf of Martin
>>> Fox<martinfox656 at gmail.com>
>>> *Date:*Monday, March 10, 2025 at 10:10
>>> *To:*Christopher Schnick<crschnick at xpipe.io>
>>> *Cc:*OpenJFX<openjfx-dev at openjdk.org>
>>> *Subject:*Re: JVM crashes on macOS when entering too many nested
>>> event loops
>>>
>>> Hi Christopher,
>>>
>>> I was able to reproduce this crash. I wrote a small routine that
>>> recursively calls itself in a runLater block and then enters a
>>> nested event loop. The program crashes when creating loop 254. I’m
>>> not sure where that limit comes from so it’s possible that consuming
>>> some other system resource could lower it. I couldn’t see any good
>>> way to determine how many loops are active by looking at the crash
>>> report since it doesn’t show the entire call stack.
>>> I did a quick trial on Linux and was able to create a lot more loops
>>> (over 600) but then started seeing erratic behavior and errors
>>> coming from the Java VM. The behavior was variable unlike on the Mac
>>> which always crashes when creating loop 254.
>>>
>>> Martin
>>>
>>> > On Mar 7, 2025, at 6:24 AM, Christopher
>>> Schnick<crschnick at xpipe.io>wrote:
>>> >
>>> > Hello,
>>> >
>>> > I have attached a JVM fatal error log that seemingly was caused by
>>> our JavaFX application entering too many nested event loops, which
>>> macOS apparently doesn't like.
>>> >
>>> > As far as I know, there is no upper limit defined on how often an
>>> event loop can be nested, so I think this is a bug that can occur in
>>> rare situations.
>>> >
>>> > Best
>>> > Christopher Schnick<hs_err_pid.txt>
>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20250312/67c08e4b/attachment-0001.htm>
More information about the openjfx-dev
mailing list