File indexing completed on 2024-05-12 15:56:57
0001 /* 0002 * SPDX-FileCopyrightText: 2013 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_assert.h" 0008 0009 #include <QString> 0010 #include <QMessageBox> 0011 #include <QThread> 0012 #include <QProcessEnvironment> 0013 #include <QCoreApplication> 0014 #include <QApplication> 0015 0016 #include <klocalizedstring.h> 0017 #include <kis_assert_exception.h> 0018 #include <KisUsageLogger.h> 0019 #include <string> 0020 #include "config-safe-asserts.h" 0021 0022 /** 0023 * TODO: Add automatic saving of the documents 0024 * 0025 * Requirements: 0026 * 1) Should save all open KisDocument objects 0027 * 2) Should *not* overwrite original document since the saving 0028 * process may fail. 0029 * 3) Should *not* overwrite any autosaved documents since the saving 0030 * process may fail. 0031 * 4) Double-fault tolerance! Assert during emergency saving should not 0032 * lead to an infinite loop. 0033 */ 0034 0035 void kis_assert_common(const char *assertion, const char *file, int line, bool throwException, bool isIgnorable) 0036 { 0037 QString shortMessage = 0038 QString("%4ASSERT (krita): \"%1\" in file %2, line %3") 0039 .arg(assertion) 0040 .arg(file) 0041 .arg(line) 0042 .arg(isIgnorable ? "SAFE " : ""); 0043 0044 QString longMessage = 0045 QString( 0046 "Krita has encountered an internal error:\n\n" 0047 "%1\n\n" 0048 "Please report a bug to developers!\n\n" 0049 "Press Ignore to try to continue.\n" 0050 "Press Abort to see developers information (all unsaved data will be lost)") 0051 .arg(shortMessage); 0052 0053 KisUsageLogger::log(shortMessage); 0054 0055 bool disableAssertMsg = 0056 QProcessEnvironment::systemEnvironment().value("KRITA_NO_ASSERT_MSG", "0").toInt(); 0057 0058 // disable message box if the assert happened in non-gui thread :( 0059 if (QThread::currentThread() != QCoreApplication::instance()->thread()) { 0060 disableAssertMsg = true; 0061 } 0062 0063 bool shouldIgnoreAsserts = false; 0064 bool forceCrashOnSafeAsserts = false; 0065 0066 #ifdef HIDE_SAFE_ASSERTS 0067 shouldIgnoreAsserts |= HIDE_SAFE_ASSERTS; 0068 #endif 0069 0070 #ifdef CRASH_ON_SAFE_ASSERTS 0071 forceCrashOnSafeAsserts |= CRASH_ON_SAFE_ASSERTS; 0072 #endif 0073 0074 disableAssertMsg |= shouldIgnoreAsserts || forceCrashOnSafeAsserts; 0075 0076 QMessageBox::StandardButton button = 0077 isIgnorable && !forceCrashOnSafeAsserts ? 0078 QMessageBox::Ignore : QMessageBox::Abort; 0079 0080 if (!disableAssertMsg) { 0081 button = 0082 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Internal Error"), 0083 longMessage, 0084 QMessageBox::Ignore | QMessageBox::Abort, 0085 QMessageBox::Ignore); 0086 } 0087 0088 if (button == QMessageBox::Abort) { 0089 qFatal("%s", shortMessage.toLatin1().data()); 0090 } else if (isIgnorable) { 0091 // Assert is a bug! Please don't change this line to warnKrita, 0092 // the user must see it! 0093 qWarning("%s", shortMessage.toLatin1().data()); 0094 } else if (throwException) { 0095 throw KisAssertException(shortMessage.toLatin1().data()); 0096 } 0097 } 0098 0099 0100 void kis_assert_recoverable(const char *assertion, const char *file, int line) 0101 { 0102 kis_assert_common(assertion, file, line, false, false); 0103 } 0104 0105 void kis_safe_assert_recoverable(const char *assertion, const char *file, int line) 0106 { 0107 kis_assert_common(assertion, file, line, false, true); 0108 } 0109 0110 void kis_assert_exception(const char *assertion, const char *file, int line) 0111 { 0112 kis_assert_common(assertion, file, line, true, false); 0113 } 0114 0115 void kis_assert_x_exception(const char *assertion, 0116 const char *where, 0117 const char *what, 0118 const char *file, int line) 0119 { 0120 QString res = 0121 QString("ASSERT failure in %1: \"%2\" (%3)") 0122 .arg(where, what, assertion); 0123 0124 kis_assert_common(res.toLatin1().data(), file, line, true, false); 0125 }