diff --git a/CMakeLists.txt b/CMakeLists.txt index 7157b223d5c..ecc9c494497 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ OPTION(WANT_VST "Include VST support" ON) OPTION(WANT_VST_NOWINE "Include partial VST support (without wine)" OFF) OPTION(WANT_WINMM "Include WinMM MIDI support" OFF) OPTION(WANT_QT5 "Build with Qt5" OFF) +OPTION(WANT_DEBUG_FPE "Debug floating point exceptions" OFF) IF(LMMS_BUILD_APPLE) @@ -420,6 +421,17 @@ IF(LMMS_BUILD_WIN32) SET(STATUS_VST "OK") ENDIF(LMMS_BUILD_WIN32) +IF(WANT_DEBUG_FPE) + IF(LMMS_BUILD_LINUX) + SET(LMMS_DEBUG_FPE TRUE) + SET (STATUS_DEBUG_FPE "Enabled") + ELSE() + SET (STATUS_DEBUG_FPE "Wanted but disabled due to unsupported platform") + ENDIF() +ELSE() + SET (STATUS_DEBUG_FPE "Disabled") +ENDIF(WANT_DEBUG_FPE) + # check for libsamplerate PKG_CHECK_MODULES(SAMPLERATE REQUIRED samplerate>=0.1.8) @@ -599,6 +611,12 @@ MESSAGE( "* GIG player : ${STATUS_GIG}\n" ) +MESSAGE( +"Developer options\n" +"-----------------------------------------\n" +"* Debug FP exceptions : ${STATUS_DEBUG_FPE}\n" +) + MESSAGE( "\n" "-----------------------------------------------------------------\n" diff --git a/src/core/main.cpp b/src/core/main.cpp index d288a0f2eb6..1363a121006 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -71,6 +71,33 @@ #include "Song.h" #include "SetupDialog.h" +#ifdef LMMS_DEBUG_FPE +#include // For feenableexcept +#include // For backtrace and backtrace_symbols_fd +#include // For STDERR_FILENO +#include // To register the signal handler +#endif + + +#ifdef LMMS_DEBUG_FPE +void signalHandler( int signum ) { + + // Get a back trace + void *array[10]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, 10); + + backtrace_symbols_fd(array, size, STDERR_FILENO); + + // cleanup and close up stuff here + // terminate program + + exit(signum); +} +#endif + static inline QString baseName( const QString & file ) { return QFileInfo( file ).absolutePath() + "/" + @@ -195,6 +222,18 @@ void fileCheck( QString &file ) int main( int argc, char * * argv ) { +#ifdef LMMS_DEBUG_FPE + // Enable exceptions for certain floating point results + feenableexcept( FE_INVALID | + FE_DIVBYZERO | + FE_OVERFLOW | + FE_UNDERFLOW); + + // Install the trap handler + // register signal SIGFPE and signal handler + signal(SIGFPE, signalHandler); +#endif + // initialize memory managers MemoryManager::init(); NotePlayHandleManager::init(); diff --git a/src/lmmsconfig.h.in b/src/lmmsconfig.h.in index 0948d8529e8..727a3e46ad2 100644 --- a/src/lmmsconfig.h.in +++ b/src/lmmsconfig.h.in @@ -21,6 +21,8 @@ #cmakedefine LMMS_HAVE_STK #cmakedefine LMMS_HAVE_VST +#cmakedefine LMMS_DEBUG_FPE + #cmakedefine LMMS_HAVE_STDINT_H #cmakedefine LMMS_HAVE_STDLIB_H #cmakedefine LMMS_HAVE_PTHREAD_H