diff --git a/src/core/debuginfo.cpp b/src/core/debuginfo.cpp index ae227f8..abc467d 100644 --- a/src/core/debuginfo.cpp +++ b/src/core/debuginfo.cpp @@ -129,12 +129,13 @@ QString envInfo() { auto stream = QTextStream(&info); for (auto** envp = environ; *envp != nullptr; ++envp) { // NOLINT - auto prefixes = std::array { + auto prefixes = std::array { "QS_", "QT_", "QML_", "QML2_", "QSG_", + "XDG_CURRENT_DESKTOP=", }; for (const auto& prefix: prefixes) { diff --git a/src/core/plugin.cpp b/src/core/plugin.cpp index 0eb9a06..e6cd1bb 100644 --- a/src/core/plugin.cpp +++ b/src/core/plugin.cpp @@ -9,6 +9,18 @@ static QVector plugins; // NOLINT void QsEnginePlugin::registerPlugin(QsEnginePlugin& plugin) { plugins.push_back(&plugin); } +void QsEnginePlugin::preinitPluginsOnly() { + plugins.removeIf([](QsEnginePlugin* plugin) { return !plugin->applies(); }); + + std::ranges::sort(plugins, [](QsEnginePlugin* a, QsEnginePlugin* b) { + return b->dependencies().contains(a->name()); + }); + + for (QsEnginePlugin* plugin: plugins) { + plugin->preinit(); + } +} + void QsEnginePlugin::initPlugins() { plugins.removeIf([](QsEnginePlugin* plugin) { return !plugin->applies(); }); @@ -16,6 +28,10 @@ void QsEnginePlugin::initPlugins() { return b->dependencies().contains(a->name()); }); + for (QsEnginePlugin* plugin: plugins) { + plugin->preinit(); + } + for (QsEnginePlugin* plugin: plugins) { plugin->init(); } diff --git a/src/core/plugin.hpp b/src/core/plugin.hpp index f0c14dc..f692e91 100644 --- a/src/core/plugin.hpp +++ b/src/core/plugin.hpp @@ -18,12 +18,14 @@ public: virtual QString name() { return QString(); } virtual QList dependencies() { return {}; } virtual bool applies() { return true; } + virtual void preinit() {} virtual void init() {} virtual void registerTypes() {} virtual void constructGeneration(EngineGeneration& /*unused*/) {} // NOLINT virtual void onReload() {} static void registerPlugin(QsEnginePlugin& plugin); + static void preinitPluginsOnly(); static void initPlugins(); static void runConstructGeneration(EngineGeneration& generation); static void runOnReload(); diff --git a/src/crash/handler.cpp b/src/crash/handler.cpp index 8f37085..33506a6 100644 --- a/src/crash/handler.cpp +++ b/src/crash/handler.cpp @@ -5,9 +5,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -58,6 +60,12 @@ void signalHandler( siginfo_t* /*info*/, // NOLINT (misc-include-cleaner) void* /*context*/ ) { + // NOLINTBEGIN (misc-include-cleaner) + sigset_t set; + sigfillset(&set); + sigprocmask(SIG_UNBLOCK, &set, nullptr); + // NOLINTEND + if (CrashInfo::INSTANCE.traceFd != -1) { auto traceBuffer = std::array(); auto frameCount = cpptrace::safe_generate_raw_trace(traceBuffer.data(), traceBuffer.size(), 1); @@ -79,13 +87,9 @@ void signalHandler( fail:; } + // TODO: coredump fork and crash reporter remain as zombies, fix auto coredumpPid = fork(); if (coredumpPid == 0) { - // NOLINTBEGIN (misc-include-cleaner) - sigset_t set; - sigfillset(&set); - sigprocmask(SIG_UNBLOCK, &set, nullptr); - // NOLINTEND raise(sig); _exit(-1); } @@ -131,7 +135,6 @@ void signalHandler( perror("Failed to fork and launch crash reporter.\n"); _exit(-1); } else if (pid == 0) { - // dup to remove CLOEXEC auto dumpFdStr = std::array(); auto logFdStr = std::array(); @@ -155,6 +158,21 @@ void signalHandler( } } +void handleCppTerminate() { + if (auto ptr = std::current_exception()) { + try { + std::rethrow_exception(ptr); + } catch (std::exception& e) { + qFatal().nospace() << "Terminate called with C++ exception (" + << cpptrace::demangle(typeid(e).name()).data() << "): " << e.what(); + } catch (...) { + qFatal() << "Terminate called with non exception object"; + } + } + + qFatal() << "Terminate called without active C++ exception"; +} + } // namespace void CrashHandler::init() { @@ -203,6 +221,8 @@ void CrashHandler::init() { // NOLINTEND (misc-include-cleaner) + std::set_terminate(&handleCppTerminate); + qCInfo(logCrashHandler) << "Crash handler initialized."; } diff --git a/src/crash/main.cpp b/src/crash/main.cpp index 30cf94d..6533b43 100644 --- a/src/crash/main.cpp +++ b/src/crash/main.cpp @@ -25,6 +25,7 @@ #include "../core/logging.hpp" #include "../core/logging_p.hpp" #include "../core/paths.hpp" +#include "../core/plugin.hpp" #include "../core/ringbuf.hpp" #include "interface.hpp" @@ -238,6 +239,9 @@ void qsCheckCrash(int argc, char** argv) { qCInfo(logCrashReporter) << "Starting crash reporter..."; + // Required platform compatibility hooks + QsEnginePlugin::preinitPluginsOnly(); + recordCrashInfo(crashDir, info.instance); auto gui = CrashReporterGui(crashDir.path(), crashProc); diff --git a/src/wayland/buffer/dmabuf.cpp b/src/wayland/buffer/dmabuf.cpp index ed9dbeb..47462fb 100644 --- a/src/wayland/buffer/dmabuf.cpp +++ b/src/wayland/buffer/dmabuf.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/src/wayland/init.cpp b/src/wayland/init.cpp index 790cebb..579e42a 100644 --- a/src/wayland/init.cpp +++ b/src/wayland/init.cpp @@ -33,8 +33,9 @@ class WaylandPlugin: public QsEnginePlugin { return isWayland; } + void preinit() override { installWlProxySafeDeref(); } + void init() override { - installWlProxySafeDeref(); installPlatformMenuHook(); installPopupPositioner(); }