Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions interface/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <plugins/DisplayPlugin.h>
#include <plugins/CodecPlugin.h>
#include <shared/GlobalAppProperties.h>
#include <fenv.h>

#include "AddressManager.h"
#include "Application.h"
Expand All @@ -49,6 +50,16 @@ extern "C" {
}
#endif

#ifdef Q_OS_UNIX
#include <csignal>
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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
20 changes: 20 additions & 0 deletions libraries/qml/src/qml/OffscreenSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <shared/ReadWriteLockable.h>
#include <NetworkingConstants.h>
#include <MetaverseAPI.h>
#include <fenv.h>

#include "Logging.h"
#include "impl/SharedObject.h"
Expand Down Expand Up @@ -457,7 +458,26 @@ 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. 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);
Comment thread
RTUnreal marked this conversation as resolved.
#endif

qmlComponent->deleteLater();
}

Expand Down
Loading