diff options
author | Robert Griebl <robert.griebl@qt.io> | 2024-03-06 15:32:08 +0100 |
---|---|---|
committer | Robert Griebl <robert.griebl@qt.io> | 2024-03-07 11:25:22 +0000 |
commit | 0b6e1dab86fcf4c4b6b2daae2beb20552be0bd59 (patch) | |
tree | 20a54ade4a6883ec927c2cb36901a30ea9d20961 /src/tools/appman/appman.cpp | |
parent | d304493eb9250d2869cd958b4c5ef87fc78b7a53 (diff) |
Fix exception handling after Q*Application::exec()
Uncaught exceptions thrown after we call exec() are originating
from user code and we should not be catching those in our top-level
catch handler. This will just print "ERROR: <what()>" without any
context and make it look like the error is coming from the AM itself.
Instead we need to run the event loop without a try/catch handler, so
stray exception from user code go directly to our set_terminate handler
in the CrashHandler class, which preserves as much context as possible
and prints out a lot more useful meta data for debugging.
Change-Id: Icc0432d5a6c5db85de439cafab89d05aa88b5891
Reviewed-by: Dominik Holland <dominik.holland@qt.io>
(cherry picked from commit 23b39347af03a40af4d19be9793f0f93a691a78f)
Diffstat (limited to 'src/tools/appman/appman.cpp')
-rw-r--r-- | src/tools/appman/appman.cpp | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/src/tools/appman/appman.cpp b/src/tools/appman/appman.cpp index 06cc3ce6..02f32424 100644 --- a/src/tools/appman/appman.cpp +++ b/src/tools/appman/appman.cpp @@ -46,26 +46,31 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) QCoreApplication::setOrganizationDomain(u"qt-project.org"_s); QCoreApplication::setApplicationVersion(QString::fromLatin1(QT_AM_VERSION_STR)); - try { - Main a(argc, argv, Main::InitFlag::ForkSudoServer | Main::InitFlag::InitializeLogging); - - Configuration cfg(additionalDescription, onlyOnePositionalArgument); - cfg.parseWithArguments(QCoreApplication::arguments()); + std::unique_ptr<Main> a; + std::unique_ptr<Configuration> cfg; -#if defined(AM_TESTRUNNER) - TestRunner::setup(&cfg); -#endif - a.setup(&cfg); - a.loadQml(cfg.loadDummyData()); - a.showWindow(cfg.fullscreen() && !cfg.noFullscreen()); + try { + a = std::make_unique<Main>(argc, argv, Main::InitFlag::ForkSudoServer + | Main::InitFlag::InitializeLogging); + cfg = std::make_unique<Configuration>(additionalDescription, onlyOnePositionalArgument); + cfg->parseWithArguments(QCoreApplication::arguments()); #if defined(AM_TESTRUNNER) - return TestRunner::exec(a.qmlEngine()); -#else - return Main::exec(); + TestRunner::setup(cfg.get()); #endif + a->setup(cfg.get()); + a->loadQml(cfg->loadDummyData()); + a->showWindow(cfg->fullscreen() && !cfg->noFullscreen()); } catch (const Exception &e) { qCCritical(LogSystem).noquote() << "ERROR:" << e.errorString(); return 2; } + + // we want the exec() outside of the try/catch block, so stray user exceptions trigger the + // CrashHandler's set_terminate callback. +#if defined(AM_TESTRUNNER) + return TestRunner::exec(a->qmlEngine()); +#else + return Main::exec(); +#endif } |