File indexing completed on 2024-05-19 04:25:03
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 abort, 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 // or if the GUI is not yet instantiated 0060 if (!QCoreApplication::instance() || QThread::currentThread() != QCoreApplication::instance()->thread()) { 0061 disableAssertMsg = true; 0062 } 0063 0064 bool shouldIgnoreAsserts = false; 0065 bool forceCrashOnSafeAsserts = false; 0066 0067 #ifdef HIDE_SAFE_ASSERTS 0068 shouldIgnoreAsserts |= HIDE_SAFE_ASSERTS; 0069 #endif 0070 0071 #ifdef CRASH_ON_SAFE_ASSERTS 0072 forceCrashOnSafeAsserts |= CRASH_ON_SAFE_ASSERTS; 0073 #endif 0074 0075 disableAssertMsg |= shouldIgnoreAsserts || forceCrashOnSafeAsserts; 0076 0077 QMessageBox::StandardButton button = 0078 isIgnorable && !forceCrashOnSafeAsserts ? 0079 QMessageBox::Ignore : QMessageBox::Abort; 0080 0081 if (!disableAssertMsg) { 0082 button = 0083 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Internal Error"), 0084 longMessage, 0085 QMessageBox::Ignore | QMessageBox::Abort, 0086 QMessageBox::Ignore); 0087 } 0088 0089 if (button == QMessageBox::Abort || abort) { 0090 qFatal("%s", shortMessage.toLatin1().data()); 0091 } else if (isIgnorable) { 0092 // Assert is a bug! Please don't change this line to warnKrita, 0093 // the user must see it! 0094 qWarning("%s", shortMessage.toLatin1().data()); 0095 } 0096 } 0097 0098 0099 void kis_assert_recoverable(const char *assertion, const char *file, int line) 0100 { 0101 kis_assert_common(assertion, file, line, false, false); 0102 } 0103 0104 void kis_safe_assert_recoverable(const char *assertion, const char *file, int line) 0105 { 0106 kis_assert_common(assertion, file, line, false, true); 0107 } 0108 0109 void kis_assert_exception(const char *assertion, const char *file, int line) 0110 { 0111 kis_assert_common(assertion, file, line, true, false); 0112 } 0113 0114 void kis_assert_x_exception(const char *assertion, 0115 const char *where, 0116 const char *what, 0117 const char *file, int line) 0118 { 0119 QString res = 0120 QString("ASSERT failure in %1: \"%2\" (%3)") 0121 .arg(where, what, assertion); 0122 0123 kis_assert_common(res.toLatin1().data(), file, line, true, false); 0124 }