From 3f70ce154f522842ebefb69e1b5e9ea9ffd543fd Mon Sep 17 00:00:00 2001 From: Vadim Troshchinskiy Date: Thu, 18 Jun 2026 20:09:08 +0200 Subject: [PATCH 1/2] Initial attempt at floating point debugging --- interface/src/main.cpp | 46 ++++++++++++++++++++++ libraries/qml/src/qml/OffscreenSurface.cpp | 11 ++++++ 2 files changed, 57 insertions(+) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 65c3d828caf..4e7c9732ee7 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "AddressManager.h" #include "Application.h" @@ -49,6 +50,16 @@ extern "C" { } #endif +#ifdef Q_OS_UNIX +#include +static int fpe_counter = 0; +static void fpe_handler(int signum) { + // This currently exists just to have something to pass to the SIGFPE handler, + // and to serve as a point where to put a breakpoint. + ++fpe_counter; +} +#endif + int main(int argc, const char* argv[]) { #ifdef Q_OS_MAC auto format = getDefaultOpenGLSurfaceFormat(); @@ -372,6 +383,11 @@ int main(int argc, const char* argv[]) { "Which graphics API to target. Supports gl45, gl41, and gles32. Final API may vary based on system support.", "string" ); + QCommandLineOption floatExceptionsOption( + "floatExcept", + "Trigger an exception for the chosen floating point conditions, comma separated: divbyzero, inexact, invalid, overflow, underflow, all. This is a debugging option.", + "string" + ); parser.addOption(urlOption); parser.addOption(protocolVersionOption); @@ -419,6 +435,8 @@ int main(int argc, const char* argv[]) { parser.addOption(xrNoHandTrackingOption); parser.addOption(xrNoPalmPoseOption); parser.addOption(graphicsAPIOption); + parser.addOption(floatExceptionsOption); + QString applicationPath; // A temporary application instance is needed to get the location of the running executable @@ -585,6 +603,34 @@ int main(int argc, const char* argv[]) { return 0; } + if (parser.isSet(floatExceptionsOption)) { + QStringList opts = parser.value(floatExceptionsOption).split(","); + int flags = 0; + + for (const auto &opt : opts) { + if (opt == "divbyzero") { + flags |= FE_DIVBYZERO; + } else if (opt == "inexact") { + flags |= FE_INEXACT; + } else if (opt == "invalid") { + flags |= FE_INVALID; + } else if (opt == "overflow") { + flags |= FE_OVERFLOW; + } else if (opt == "underflow") { + flags |= FE_UNDERFLOW; + } else if (opt == "all") { + flags = FE_ALL_EXCEPT; + } else { + qCritical() << "Invalid value for --floatExcept option: " << opt; + return 2; + } + } + + feenableexcept(flags); +#ifdef Q_OS_UNIX + signal(SIGFPE, fpe_handler); +#endif + } static const QString APPLICATION_CONFIG_FILENAME = "config.json"; QDir applicationDir(applicationPath); diff --git a/libraries/qml/src/qml/OffscreenSurface.cpp b/libraries/qml/src/qml/OffscreenSurface.cpp index aabe6f36ba5..a6d3befc7b0 100644 --- a/libraries/qml/src/qml/OffscreenSurface.cpp +++ b/libraries/qml/src/qml/OffscreenSurface.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "Logging.h" #include "impl/SharedObject.h" @@ -457,7 +458,17 @@ void OffscreenSurface::finishQmlLoad(QQmlComponent* qmlComponent, // Call this callback after rootitem is set, otherwise VrMenu wont work callback(qmlContext, newItem); } + + // There's a huge amount of divides by zero that happen with floating point exceptions + // enabled. It makes useful debugging impossible, so we're selectively disabling them + // here. + fexcept_t fflags; + + fegetexceptflag(&fflags, FE_ALL_EXCEPT); + fedisableexcept(FE_ALL_EXCEPT); qmlComponent->completeCreate(); + + fesetexceptflag(&fflags, FE_ALL_EXCEPT); qmlComponent->deleteLater(); } From ebd8abd52d8e4108f6532b3e237503e7e39793cf Mon Sep 17 00:00:00 2001 From: Vadim Troshchinskiy Date: Wed, 24 Jun 2026 23:58:44 +0200 Subject: [PATCH 2/2] Do not disable FP exceptions on Windows, unsupported --- libraries/qml/src/qml/OffscreenSurface.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libraries/qml/src/qml/OffscreenSurface.cpp b/libraries/qml/src/qml/OffscreenSurface.cpp index a6d3befc7b0..d788064d5f4 100644 --- a/libraries/qml/src/qml/OffscreenSurface.cpp +++ b/libraries/qml/src/qml/OffscreenSurface.cpp @@ -461,14 +461,23 @@ void OffscreenSurface::finishQmlLoad(QQmlComponent* qmlComponent, // There's a huge amount of divides by zero that happen with floating point exceptions // enabled. It makes useful debugging impossible, so we're selectively disabling them - // here. + // here. Unfortunately fedisableexcept isn't standard and not available on Windows. + // + // On Windows, this might be unusable. Perhaps some sort of modification to QML + // might be possible. +#ifndef Q_OS_WIN fexcept_t fflags; fegetexceptflag(&fflags, FE_ALL_EXCEPT); fedisableexcept(FE_ALL_EXCEPT); +#endif + qmlComponent->completeCreate(); +#ifndef Q_OS_WIN fesetexceptflag(&fflags, FE_ALL_EXCEPT); +#endif + qmlComponent->deleteLater(); }