Yes, thank you Christopher for providing a reproducible test case! I was able to trigger the problem on my Mac on the first try. Since I’m using a modified version of JavaFX the system didn’t crash but instead hit a Java stack overflow error and produced a very long stack trace.
At least on the Mac the problem seems to be that you’re trying to pop an Alert containing a long stack trace. While trying to adjust the Alert’s bounds JavaFX is throwing another exception but I’m not sure why. I’ll continue to look into it. Thanks again, Martin > On Mar 25, 2025, at 12:16 PM, Andy Goryachev <andy.goryac...@oracle.com> > wrote: > > Thank you, Christopher, for clarification! > > Personally, I would consider this to be a problem with the application > design: the code should limit the number of alerts shown to the user. Do you > really want the user to click through hundreds of alerts? > > Nevertheless, you are right about the need for the platform to gracefully > handle the case of too many nested event loops - by throwing an exception > with a meaningful message, as Martin proposed in > https://github.com/openjdk/jfx/pull/1741 > > Cheers, > -andy > > > > From: Christopher Schnick <crschn...@xpipe.io> > Date: Tuesday, March 25, 2025 at 11:52 > To: Andy Goryachev <andy.goryac...@oracle.com> > Cc: OpenJFX <openjfx-dev@openjdk.org> > Subject: Re: [External] : Re: JVM crashes on macOS when entering too many > nested event loops > > Hey Andy, > > so I think I was able to reproduce this issue for our application. > > There are two main factors how this can happen: > - We use an alert-based error reporter, meaning that we have a default > uncaught exception handler set for all threads which will showAndWait an > Alert with the exception message > - As I reported yesterday with > https://mail.openjdk.org/pipermail/openjfx-dev/2025-March/052963.html, there > are some rare exceptions that can occur in a normal event loop without > interference of the application, probably because of a small bug in the > bounds calculation code > > If you combine these two factors, you will end up with an infinite loop of > the showAndWait entering a nested event loop, the event loop throwing an > internal exception, and the uncaught exception handler starting the same loop > with another alert. I don't think this is a bad implementation from our side, > the only thing that we can improve is to maybe check how deep the uncaught > exception loop is in to prevent this from occurring indefinitely. But I would > argue this can happen to any application. Here is a sample code, based on the > reproducer from the OutOfBounds report from yesterday: > > import javafx.application.Application; > import javafx.application.Platform; > import javafx.scene.Scene; > import javafx.scene.control.Alert; > import javafx.scene.control.Button; > import javafx.scene.layout.Region; > import javafx.scene.layout.StackPane; > import javafx.scene.layout.VBox; > import javafx.stage.Stage; > > import java.io.IOException; > import java.util.Arrays; > > public class ParentBoundsBug extends Application { > > @Override > public void start(Stage stage) throws IOException { > Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { > throwable.printStackTrace(); > > if (Platform.isFxApplicationThread()) { > var alert = new Alert(Alert.AlertType.ERROR); > alert.setHeaderText(throwable.getMessage()); > > alert.setContentText(Arrays.toString(throwable.getStackTrace())); > alert.showAndWait(); > } else { > // Do some other error handling for non-platform threads > // Probably just show the alert with a runLater() > > // For this example, there are no exceptions outside the > platform thread > } > }); > > // Run delayed as Application::reportException will only be called > for exceptions > // after the application has started > Platform.runLater(() -> { > Scene scene = new Scene(createContent(), 640, 480); > stage.setScene(scene); > stage.show(); > stage.centerOnScreen(); > }); > } > > private Region createContent() { > var b1 = new Button("Click me!"); > var b2 = new Button("Click me!"); > var vbox = new VBox(b1, b2); > b1.boundsInParentProperty().addListener((observable, oldValue, > newValue) -> { > vbox.setVisible(!vbox.isVisible()); > }); > b2.boundsInParentProperty().addListener((observable, oldValue, > newValue) -> { > vbox.setVisible(!vbox.isVisible()); > }); > vbox.boundsInParentProperty().addListener((observable, oldValue, > newValue) -> { > vbox.setVisible(!vbox.isVisible()); > }); > > var stack = new StackPane(vbox, new StackPane()); > stack.boundsInParentProperty().addListener((observable, oldValue, > newValue) -> { > vbox.setVisible(!vbox.isVisible()); > }); > return stack; > } > > public static void main(String[] args) { > launch(); > } > } > > If the same OutOfBounds exception from the reported I linked happens in the > bounds calculation, which happens approximately 1/5 runs for me, this > application will enter new event loops until it crashes. If the OutOfBounds > doesn't trigger, it will just throw a StackOverflow but won't continue the > infinite loop of nested event loops. So for the reproducer it is important to > try a few times until you get the described OutOfBounds. > > I attached the stacktrace of how this fails. The initial StackOverflow causes > infinitely many following exceptions in the nested event loop. > > Best > Christopher Schnick > > On 25/03/2025 18:28, Andy Goryachev wrote: > Dear Christopher: > > Were you able to root cause why your application enters that many nested > event loops? > > I believe a well-behaved application should never experience that, unless > there is some design flaw or a bug. > > -andy > > > From: Christopher Schnick <crschn...@xpipe.io> <mailto:crschn...@xpipe.io> > Date: Monday, March 10, 2025 at 19:45 > To: Andy Goryachev <andy.goryac...@oracle.com> > <mailto:andy.goryac...@oracle.com> > Subject: [External] : Re: JVM crashes on macOS when entering too many nested > event loops > > 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-r...@openjdk.org> > <mailto:openjfx-dev-r...@openjdk.org> on behalf of Martin Fox > <martinfox...@gmail.com> <mailto:martinfox...@gmail.com> > Date: Monday, March 10, 2025 at 10:10 > To: Christopher Schnick <crschn...@xpipe.io> <mailto:crschn...@xpipe.io> > Cc: OpenJFX <openjfx-dev@openjdk.org> <mailto:openjfx-dev@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 <crschn...@xpipe.io> > > <mailto:crschn...@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> >