From 704d17557bcebe98ccf8f3682b02f0d541f6db61 Mon Sep 17 00:00:00 2001 From: Andras Lasso Date: Fri, 25 Jan 2019 12:07:13 -0500 Subject: [PATCH] Fix QtDesigner crash in debug mode Debug-mode Qt Designer crashed when tried to instantiate a ctkMatrixWidget because of an assert failure. It may be useful to know that some operations fail, but making the Qt Designer crash is a too strong way of notifying developers (especially when developers only use CTK and not intend to fix its potential internal errors). Fixed by adding a new CTK_SOFT_ASSERT macro that just logs a warning instead of terminating the application (and does it both in debug and release mode, to make application behavior consistent). It should be possible to use this macro instead of Q_ASSSERT where crashing the application in unexpected situations in debug mode should be avoided. --- Libs/Core/Testing/Cpp/ctkLoggerTest1.cpp | 7 +++++++ Libs/Core/ctkUtils.h | 15 +++++++++++++++ Libs/Widgets/ctkMatrixWidget.cpp | 5 +++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Libs/Core/Testing/Cpp/ctkLoggerTest1.cpp b/Libs/Core/Testing/Cpp/ctkLoggerTest1.cpp index a36060d22f..3bfaa385b1 100644 --- a/Libs/Core/Testing/Cpp/ctkLoggerTest1.cpp +++ b/Libs/Core/Testing/Cpp/ctkLoggerTest1.cpp @@ -23,6 +23,7 @@ // CTK includes #include +#include // STL includes #include @@ -43,6 +44,12 @@ int ctkLoggerTest1(int argc, char * argv [] ) logger.error("logger.error"); logger.fatal("logger.fatal"); + // This should log a warning "Assertion `5 == 6` failed ..." + CTK_SOFT_ASSERT(5 == 6); + + // This should not log anything + CTK_SOFT_ASSERT(8 == 8); + return EXIT_SUCCESS; } diff --git a/Libs/Core/ctkUtils.h b/Libs/Core/ctkUtils.h index 92d1888608..8d4383d183 100644 --- a/Libs/Core/ctkUtils.h +++ b/Libs/Core/ctkUtils.h @@ -24,12 +24,27 @@ // Qt includes #include #include +#include // STD includes #include #include "ctkCoreExport.h" +/// This macro can be used instead of Q_ASSERT to warn developers +/// when some assumption fails. CTK_SOFT_ASSERT behavior differs +/// in two key aspects: (1) it only logs a warning (instead of terminating +/// the application) and (2) the message is always logged (instead of +/// ignoring the check in release builds). +#define CTK_SOFT_ASSERT(condition) do \ + { \ + if (! (condition) ) \ + { \ + qWarning() << "Assertion `" #condition "` failed in " << __FILE__ \ + << " line " << __LINE__; \ + } \ + } while (false) + namespace ctk { /// /// \ingroup Core diff --git a/Libs/Widgets/ctkMatrixWidget.cpp b/Libs/Widgets/ctkMatrixWidget.cpp index 32e5ffa656..b8780166da 100644 --- a/Libs/Widgets/ctkMatrixWidget.cpp +++ b/Libs/Widgets/ctkMatrixWidget.cpp @@ -21,6 +21,7 @@ // CTK includes #include "ctkMatrixWidget.h" #include "ctkDoubleSpinBox.h" +#include "ctkUtils.h" // Qt includes #include @@ -238,7 +239,7 @@ void ctkMatrixWidgetPrivate::updateGeometries() bool lastColumn = (j==(ccount-1)); int newWidth = lastColumn ? lastColWidth : colWidth; this->Table->setColumnWidth(j, newWidth); - Q_ASSERT(this->Table->columnWidth(j) == newWidth); + CTK_SOFT_ASSERT(this->Table->columnWidth(j) == newWidth); } // rows const int rcount = q->rowCount(); @@ -249,7 +250,7 @@ void ctkMatrixWidgetPrivate::updateGeometries() bool lastRow = (i==(rcount-1)); int newHeight = lastRow ? lastRowHeight : rowHeight; this->Table->setRowHeight(i, newHeight); - Q_ASSERT(this->Table->rowHeight(i) == newHeight); + CTK_SOFT_ASSERT(this->Table->rowHeight(i) == newHeight); } this->Table->updateGeometry(); }