Skip to content
Snippets Groups Projects
Commit 27716f28 authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

Assert under GUI: debug mode, raise SIGTERM. Add explanations

parent 3bfde60d
No related branches found
No related tags found
1 merge request!1393ASSERT uses function pointer to call qFatal, so that core must not depend on Qt (#494)
Pipeline #90595 passed
...@@ -28,6 +28,15 @@ ...@@ -28,6 +28,15 @@
#include <QMetaType> #include <QMetaType>
#include <QtGlobal> #include <QtGlobal>
auto guiFailedAssertion = [](std::string msg) {
#ifdef BA_DEBUG
std::cerr << "FATAL (catched in debug mode): " << msg << std::endl;
std::raise(11); // abort so that we can inspect the backtrace
#else
qFatal(msg.c_str());
#endif
};
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
ApplicationOptions options(argc, argv); ApplicationOptions options(argc, argv);
...@@ -46,7 +55,7 @@ int main(int argc, char* argv[]) ...@@ -46,7 +55,7 @@ int main(int argc, char* argv[])
ApplicationSettings applicationSettings; ApplicationSettings applicationSettings;
qInstallMessageHandler(messageHandler); qInstallMessageHandler(messageHandler);
failedAssertion = [](std::string msg) { qFatal(msg.c_str()); }; failedAssertion = guiFailedAssertion;
register1DDataLoaders(); register1DDataLoaders();
......
...@@ -13,14 +13,7 @@ ...@@ -13,14 +13,7 @@
// ************************************************************************************************ // ************************************************************************************************
#include "Base/Util/Assert.h" #include "Base/Util/Assert.h"
#include <csignal>
#include <iostream>
std::function<void(std::string)> failedAssertion = [](std::string msg) { std::function<void(std::string)> failedAssertion = [](std::string msg) {
#ifdef BA_DEBUG
std::cerr << msg << std::endl;
std::raise(11); // abort so that we can inspect the backtrace
#else
throw std::runtime_error(msg); throw std::runtime_error(msg);
#endif
}; };
...@@ -20,23 +20,46 @@ ...@@ -20,23 +20,46 @@
#include "Wrap/WinDllMacros.h" #include "Wrap/WinDllMacros.h"
#include <functional> #include <functional>
#include <sstream>
#include <stdexcept>
#include <string> #include <string>
// Function called upon failed assert; set in Assert.cpp, overriden by GUI. // Function called upon failed assert; set in Assert.cpp, overriden by GUI.
extern BA_BASE_API_ std::function<void(std::string)> failedAssertion; extern BA_BASE_API_ std::function<void(std::string)> failedAssertion;
// ASSERT must be declared as a macro, not a function, in order for the error // ASSERT macro: terminate if condition is false.
// message to correctly report the source line where the assertion failed. //
// Implementation notes:
// - Must be declared as a macro, not a function, so that we can use preprocessor
// macros for informative error messages.
// - Must terminate with a throw statement to prevent compiler warning -Wreturn-type.
// - In the GUI, the function pointer failedAssertion will be reset to call qFatal,
// which then pops up a message window (as defined by qInstallMessageHandler).
// - No direct call to qFatal here, because we do not want core to depend on Qt,
// lest Python wheel becomes too difficult.
#ifdef BA_DEBUG
#include <csignal>
#include <iostream>
#define ASSERT(condition) \
if (!(condition)) { \
std::cerr << "Assertion " << (#condition) << " failed in " << __FILE__ << ", line " \
<< __LINE__ << std::endl; \
std::raise(SIGTERM); /* abort so that we can inspect the backtrace */ \
throw std::runtime_error("Assertion failed ... and we should never get here"); \
}
#else
#include <sstream>
#include <stdexcept>
#define ASSERT(condition) \ #define ASSERT(condition) \
if (!(condition)) { \ if (!(condition)) { \
std::stringstream msg; \ std::stringstream msg; \
msg << "Assertion " << (#condition) << " failed in " << __FILE__ << ", line " << __LINE__; \ msg << "Assertion " << (#condition) << " failed in " << __FILE__ << ", line " << __LINE__; \
failedAssertion(msg.str()); \ failedAssertion(msg.str()); \
/* The following throw is needed to prevent compiler warning -Wreturn-type */ \
throw std::runtime_error("Assertion failed ... and we should never get here"); \ throw std::runtime_error("Assertion failed ... and we should never get here"); \
} }
#endif // BA_DEBUG
#endif // BORNAGAIN_BASE_UTIL_ASSERT_H #endif // BORNAGAIN_BASE_UTIL_ASSERT_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment