Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kf6-kcrash for openSUSE:Factory checked in at 2026-02-16 13:01:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kf6-kcrash (Old) and /work/SRC/openSUSE:Factory/.kf6-kcrash.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kf6-kcrash" Mon Feb 16 13:01:13 2026 rev:24 rq:1332919 version:6.23.0 Changes: -------- --- /work/SRC/openSUSE:Factory/kf6-kcrash/kf6-kcrash.changes 2026-01-12 10:15:03.982064797 +0100 +++ /work/SRC/openSUSE:Factory/.kf6-kcrash.new.1977/kf6-kcrash.changes 2026-02-16 13:04:38.106348706 +0100 @@ -1,0 +2,16 @@ +Fri Feb 6 14:25:47 UTC 2026 - Christophe Marin <[email protected]> + +- Update to 6.23.0 + * New feature release + * For more details please see: + * https://kde.org/announcements/frameworks/6/6.23.0 +- Changes since 6.22.0: + * Avoid using qEnvironmentVariableIntegerValue + * Update dependency version to 6.23.0 + * autotests: make sure to cover metadata in main test + * metadata: write a completion marker group + * Guard qGuiApp having already been torn down + * Enable LSAN in CI + * Update version to 6.23.0 + +------------------------------------------------------------------- Old: ---- kcrash-6.22.0.tar.xz kcrash-6.22.0.tar.xz.sig New: ---- kcrash-6.23.0.tar.xz kcrash-6.23.0.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kf6-kcrash.spec ++++++ --- /var/tmp/diff_new_pack.G08rOH/_old 2026-02-16 13:04:40.922470730 +0100 +++ /var/tmp/diff_new_pack.G08rOH/_new 2026-02-16 13:04:40.926470904 +0100 @@ -19,11 +19,11 @@ %define qt6_version 6.8.0 %define rname kcrash -# Full KF6 version (e.g. 6.22.0) +# Full KF6 version (e.g. 6.23.0) %{!?_kf6_version: %global _kf6_version %{version}} %bcond_without released Name: kf6-kcrash -Version: 6.22.0 +Version: 6.23.0 Release: 0 Summary: An application crash handler License: LGPL-2.1-or-later ++++++ kcrash-6.22.0.tar.xz -> kcrash-6.23.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcrash-6.22.0/.kde-ci.yml new/kcrash-6.23.0/.kde-ci.yml --- old/kcrash-6.22.0/.kde-ci.yml 2026-01-02 18:41:14.000000000 +0100 +++ new/kcrash-6.23.0/.kde-ci.yml 2026-02-13 13:13:58.000000000 +0100 @@ -7,3 +7,4 @@ Options: test-before-installing: true require-passing-tests-on: ['Linux', 'FreeBSD', 'Windows'] + enable-lsan: True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcrash-6.22.0/CMakeLists.txt new/kcrash-6.23.0/CMakeLists.txt --- old/kcrash-6.22.0/CMakeLists.txt 2026-01-02 18:41:14.000000000 +0100 +++ new/kcrash-6.23.0/CMakeLists.txt 2026-02-13 13:13:58.000000000 +0100 @@ -1,14 +1,14 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.27) -set(KF_VERSION "6.22.0") # handled by release scripts -set(KF_DEP_VERSION "6.22.0") # handled by release scripts +set(KF_VERSION "6.23.0") # handled by release scripts +set(KF_DEP_VERSION "6.23.0") # handled by release scripts project(KCrash VERSION ${KF_VERSION}) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) include(FeatureSummary) -find_package(ECM 6.22.0 NO_MODULE) +find_package(ECM 6.23.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcrash-6.22.0/autotests/kcrashtest.cpp new/kcrash-6.23.0/autotests/kcrashtest.cpp --- old/kcrash-6.22.0/autotests/kcrashtest.cpp 2026-01-02 18:41:14.000000000 +0100 +++ new/kcrash-6.23.0/autotests/kcrashtest.cpp 2026-02-13 13:13:58.000000000 +0100 @@ -8,8 +8,14 @@ #include <QDebug> #include <QFile> #include <QProcess> +#include <QTemporaryDir> #include <QTest> +namespace +{ +const QString s_testMetadataFile = QDir::homePath() + "/.qttest/cache/kcrash-metadata/test.ini"; +} // namespace + class KCrashTest : public QObject { Q_OBJECT @@ -21,9 +27,14 @@ // change to the bin dir QDir::setCurrent(QCoreApplication::applicationDirPath()); } + void init() + { + QFile::remove(s_testMetadataFile); + } void testAutoRestart(); void testAutoRestartDirectly(); void testEmergencySave(); + void testPartialMetadata(); }; static const char s_logFileName[] = "kcrashtest_log"; @@ -37,7 +48,7 @@ return logFile.readAll(); } -static void startCrasher(const QByteArray &flag, const QByteArray &expectedOutput) +static void startCrasher(const QByteArray &flag, const QByteArray &expectedOutput, const QHash<QString, QString> &extraEnv = {}) { QFile::remove(QFile::encodeName(s_logFileName)); @@ -53,6 +64,9 @@ // qDebug() << proc.args(); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert(QStringLiteral("ASAN_OPTIONS"), QStringLiteral("handle_segv=0,poison_heap=0")); // Disable ASAN + for (const auto &[key, value] : extraEnv.asKeyValueRange()) { + env.insert(key, value); + } proc.setProcessEnvironment(env); proc.setProcessChannelMode(QProcess::ForwardedChannels); proc.start(processName, QStringList() << flag); @@ -74,6 +88,15 @@ void KCrashTest::testAutoRestart() // use kdeinit if possible, otherwise directly (ex: on CI) { startCrasher("AR", "starting AR\nautorestarted AR\n"); + +#if defined(Q_OS_LINUX) + // Complete metadata file should have been written + QFile testFile(s_testMetadataFile); + QVERIFY(testFile.open(QIODevice::ReadOnly)); + const QByteArray content = testFile.readAll(); + QVERIFY(content.contains("[KCrash]\n")); + QVERIFY(content.contains("[KCrashComplete]\n")); +#endif } void KCrashTest::testAutoRestartDirectly() // test directly (so a developer can test the CI case) @@ -86,6 +109,20 @@ startCrasher("ES", "starting ES\nsaveFunction called\n"); } +void KCrashTest::testPartialMetadata() +{ + startCrasher("PartialMetadata", "PartialMetadata\n", {{"KCRASH_CRASH_IN_HANDLER", "1"}}); + +#if defined(Q_OS_LINUX) + // The file should not contain [KCrashComplete] since the crash happened after QApplication destruction + QFile testFile(s_testMetadataFile); + QVERIFY(testFile.open(QIODevice::ReadOnly)); + const QByteArray content = testFile.readAll(); + QVERIFY(content.contains("[KCrash]\n")); // But it should contain the KCrash section + QVERIFY(!content.contains("[KCrashComplete]\n")); +#endif +} + QTEST_MAIN(KCrashTest) #include "kcrashtest.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcrash-6.22.0/autotests/metadatatest.cpp new/kcrash-6.23.0/autotests/metadatatest.cpp --- old/kcrash-6.22.0/autotests/metadatatest.cpp 2026-01-02 18:41:14.000000000 +0100 +++ new/kcrash-6.23.0/autotests/metadatatest.cpp 2026-02-13 13:13:58.000000000 +0100 @@ -43,6 +43,7 @@ QCOMPARE(ini.readLine(), "[KCrash]\n"); QCOMPARE(ini.readLine(), "ABC=FOO\\nBAR\n"); QCOMPARE(ini.readLine(), "Meow=true\n"); + QCOMPARE(ini.readLine(), "[KCrashComplete]\n"); QVERIFY(ini.atEnd()); // nothing after final newline #endif } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcrash-6.22.0/autotests/test_crasher.cpp new/kcrash-6.23.0/autotests/test_crasher.cpp --- old/kcrash-6.22.0/autotests/test_crasher.cpp 2026-01-02 18:41:14.000000000 +0100 +++ new/kcrash-6.23.0/autotests/test_crasher.cpp 2026-02-13 13:13:58.000000000 +0100 @@ -8,6 +8,7 @@ #include <QApplication> #include <QDebug> #include <QFile> +#include <QStandardPaths> #include <kcrash.h> #ifdef Q_OS_UNIX #include <cerrno> @@ -24,6 +25,7 @@ int main(int argc, char **argv) { + QStandardPaths::setTestModeEnabled(true); QApplication app(argc, argv); KCrash::initialize(); @@ -53,7 +55,12 @@ if (!output.open(QIODevice::WriteOnly | QIODevice::Append)) { return 1; } - if (qEnvironmentVariableIsEmpty("KCRASH_AUTO_RESTARTED")) { + + if (flag == "PartialMetadata") { + output.write("PartialMetadata\n"); + output.flush(); + delete (char *)0xdead; + } else if (qEnvironmentVariableIsEmpty("KCRASH_AUTO_RESTARTED")) { output.write("starting "); output.write(flag); output.write("\n"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcrash-6.22.0/src/kcrash.cpp new/kcrash-6.23.0/src/kcrash.cpp --- old/kcrash-6.22.0/src/kcrash.cpp 2026-01-02 18:41:14.000000000 +0100 +++ new/kcrash-6.23.0/src/kcrash.cpp 2026-02-13 13:13:58.000000000 +0100 @@ -118,6 +118,7 @@ static int s_launchDrKonqi = -1; // -1=initial value 0=disabled 1=enabled static int s_originalSignal = -1; static QByteArray s_metadataPath; +static const bool s_crashInHandler = qEnvironmentVariableIntValue("KCRASH_CRASH_IN_HANDLER") == 1; static std::unique_ptr<char[]> s_kcrashErrorMessage; @@ -173,6 +174,9 @@ static bool shouldWriteMetadataToDisk() { #ifdef Q_OS_LINUX + if (QStandardPaths::isTestModeEnabled()) { + return true; + } // NB: The daemon being currently running must not be a condition here. If something crashes during logout // the daemon may already be gone but we'll still want to deal with the crash on next login! // Similar reasoning applies to not checking the presence of the launcher socket. @@ -222,11 +226,15 @@ // This data is consumed by DrKonqi in combination with coredumpd metadata. const QString metadataDir = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QStringLiteral("/kcrash-metadata"); if (QDir().mkpath(metadataDir)) { - const auto bootId = ::bootId(); - const auto exe = QString::fromUtf8(s_appName.get()); - const auto pid = QString::number(QCoreApplication::applicationPid()); - s_metadataPath = QFile::encodeName(metadataDir + // - QStringLiteral("/%1.%2.%3.ini").arg(exe, bootId, pid)); + if (QStandardPaths::isTestModeEnabled()) { + s_metadataPath = QFile::encodeName(metadataDir + QStringLiteral("/test.ini")); + } else { + const auto bootId = ::bootId(); + const auto exe = QString::fromUtf8(s_appName.get()); + const auto pid = QString::number(QCoreApplication::applicationPid()); + s_metadataPath = QFile::encodeName(metadataDir + // + QStringLiteral("/%1.%2.%3.ini").arg(exe, bootId, pid)); + } } if (!s_crashHandler) { // Always enable the default handler. We cannot create the metadata ahead of time since we do not know @@ -535,9 +543,12 @@ if (platformName == QByteArrayLiteral("xcb")) { // start up on the correct display char *display = nullptr; - if (auto disp = qGuiApp->nativeInterface<QNativeInterface::QX11Application>()->display()) { - display = XDisplayString(disp); - } else { + if (qGuiApp) { + if (auto disp = qGuiApp->nativeInterface<QNativeInterface::QX11Application>()->display()) { + display = XDisplayString(disp); + } + } + if (!display) { display = getenv("DISPLAY"); } data.add("--display", display); @@ -593,6 +604,13 @@ data.add("--thread", threadId); #endif + if (s_crashInHandler) { +#if !defined(Q_OS_WIN) + kill(getpid(), SIGSEGV); +#endif + return; // we may continue running a couple ms after the segv. return so we don't close the data! + } + data.close(); const int argc = data.argc; const char **argv = data.argv.data(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcrash-6.22.0/src/metadata.cpp new/kcrash-6.23.0/src/metadata.cpp --- old/kcrash-6.22.0/src/metadata.cpp 2026-01-02 18:41:14.000000000 +0100 +++ new/kcrash-6.23.0/src/metadata.cpp 2026-02-13 13:13:58.000000000 +0100 @@ -72,8 +72,12 @@ void MetadataINIWriter::close() { - if (fd >= 0 && ::close(fd) == -1) { - fprintf(stderr, "Failed to close metadata file: %s\n", strerror(errno)); + if (fd >= 0) { + constexpr std::string_view endGroup = "[KCrashComplete]\n"; + write(fd, endGroup.data(), endGroup.size()); + if (::close(fd) == -1) { + fprintf(stderr, "Failed to close metadata file: %s\n", strerror(errno)); + } } writable = false; }
