diff --git a/.gitlab-ci-files/macosx-desktop.yml b/.gitlab-ci-files/macosx-desktop.yml index 4d20bc3f5..fb7bad227 100644 --- a/.gitlab-ci-files/macosx-desktop.yml +++ b/.gitlab-ci-files/macosx-desktop.yml @@ -102,7 +102,7 @@ macosx-ninja-package: - if: $PACKAGE_MACOSX - if: $DEPLOY_MACOSX variables: - CMAKE_OPTIONS: -DPython3_ROOT_DIR=/opt/bc/pip-packages/ -DENABLE_APP_PACKAGING=ON -DENABLE_GPL_THIRD_PARTIES=OFF -DENABLE_G729=ON -DENABLE_BUGSPLAT_SYMBOLS_UPLOAD=ON -DBUGSPLAT_CLIENT_ID=$BUGSPLAT_CLIENT_ID -DBUGSPLAT_CLIENT_SECRET=$BUGSPLAT_CLIENT_SECRET -DBUGSPLAT_DATABASE=$BUGSPLAT_DATABASE + CMAKE_OPTIONS: -DPython3_ROOT_DIR=/opt/bc/pip-packages/ -DENABLE_APP_PACKAGING=ON -DENABLE_GPL_THIRD_PARTIES=OFF -DENABLE_G729=ON -DBUGSPLAT_CLIENT_ID=$BUGSPLAT_CLIENT_ID -DBUGSPLAT_CLIENT_SECRET=$BUGSPLAT_CLIENT_SECRET -DBUGSPLAT_DATABASE=$BUGSPLAT_DATABASE RELEASE_FILE: -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$MACOSX_PLATFORM/$APP_FOLDER extends: macosx-ninja script: diff --git a/.gitlab-ci-files/windows-desktop.yml b/.gitlab-ci-files/windows-desktop.yml index bd475dc94..30f9d47e1 100644 --- a/.gitlab-ci-files/windows-desktop.yml +++ b/.gitlab-ci-files/windows-desktop.yml @@ -181,21 +181,22 @@ win64-ninja-vs2022-scheduled-windows: rules: - !reference [.rules-merge-request-manual, rules] - if: $NIGHTLY_RELEASE - - if: $PACKAGE_WINDOWS - variables: - CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES -DENABLE_G729=ON -DENABLE_PQCRYPTO=ON -DENABLE_GPL_THIRD_PARTIES=OFF - RELEASE_FILE: -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$WINDOWS_PLATFORM/$APP_FOLDER - -.vs-win64-package-cr: - stage: package - needs: [] - rules: - if: $NIGHTLY_MASTER - - if: $DEPLOY_WINDOWS + - if: $PACKAGE_WINDOWS variables: CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES -DENABLE_G729=ON -DENABLE_PQCRYPTO=ON -DENABLE_GPL_THIRD_PARTIES=OFF -DENABLE_BUGSPLAT_SYMBOLS_UPLOAD=ON -DBUGSPLAT_CLIENT_ID=$BUGSPLAT_CLIENT_ID -DBUGSPLAT_CLIENT_SECRET=$BUGSPLAT_CLIENT_SECRET -DBUGSPLAT_DATABASE=$BUGSPLAT_DATABASE RELEASE_FILE: -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$WINDOWS_PLATFORM/$APP_FOLDER +# .vs-win64-package-cr: +# stage: package +# needs: [] +# rules: +# - if: $NIGHTLY_MASTER +# - if: $DEPLOY_WINDOWS +# variables: +# CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES -DENABLE_G729=ON -DENABLE_PQCRYPTO=ON -DENABLE_GPL_THIRD_PARTIES=OFF -DENABLE_BUGSPLAT_SYMBOLS_UPLOAD=ON -DBUGSPLAT_CLIENT_ID=$BUGSPLAT_CLIENT_ID -DBUGSPLAT_CLIENT_SECRET=$BUGSPLAT_CLIENT_SECRET -DBUGSPLAT_DATABASE=$BUGSPLAT_DATABASE +# RELEASE_FILE: -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$WINDOWS_PLATFORM/$APP_FOLDER + win64-ninja-vs2022-package-windows: variables: CMAKE_GENERATOR: "Ninja" @@ -207,15 +208,15 @@ win64-ninja-vs2022-package-windows: - .vs-win64-package #Packaging for deployment (Upload symbols at the same time of the packaging) -win64-ninja-vs2022-package-cr-windows: - variables: - CMAKE_GENERATOR: "Ninja" - CMAKE_ARCHITECTURE: "" - PARALLEL_OPTIONS: "" - extends: - - .windows-vs2022 - - .windows-ninja-variables - - .vs-win64-package-cr +# win64-ninja-vs2022-package-cr-windows: +# variables: +# CMAKE_GENERATOR: "Ninja" +# CMAKE_ARCHITECTURE: "" +# PARALLEL_OPTIONS: "" +# extends: +# - .windows-vs2022 +# - .windows-ninja-variables +# - .vs-win64-package-cr ################################################# @@ -244,28 +245,6 @@ win64-codesigning: when: always expire_in: 1 week -win64-codesigning-cr: - stage: signing - allow_failure: true - extends: - - .windows-codesigning - needs: - - win64-ninja-vs2022-package-cr-windows - variables: - MINGW_TYPE: mingw64 - rules: - - if: $NIGHTLY_MASTER - - if: $DEPLOY_WINDOWS - script: - - cd build-desktop/OUTPUT/Packages/ - - Invoke-Expression "& ${WINDOWS_SIGN_TOOL} sign /fd SHA256 /t ${WINDOWS_SIGN_TIMESTAMP_URL} /sha1 ${WINDOWS_SIGN_HASH} *.exe" - - 'if (-not ($LastExitCode -eq 0)) {throw "Error: Signature failed"}' - artifacts: - paths: - - build-desktop\OUTPUT\Packages\* - when: always - expire_in: 1 week - ################################################# # DEPLOY ################################################# @@ -286,7 +265,7 @@ win64-ninja-vs2022-upload: extends: - .win64-upload needs: - - win64-codesigning-cr + - win64-codesigning .win64-plugins-upload: stage: deploy diff --git a/CMakeLists.txt b/CMakeLists.txt index 793a4bb15..e1766fbb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,7 +244,10 @@ if(NOT APPLE OR MONO_ARCH) add_external() endif() if(TARGET Crashpad) + message(DEBUG "Target Crashpad, enable crash handler") set(HAVE_CRASH_HANDLER 1) + else() + message(DEBUG "Target is not Crashpad, disable crash handler") endif() function(add_linphone_app) set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) # Prevent project from overriding the options we just set here diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index dfbff4b53..46f768841 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -314,8 +314,11 @@ App::App(int &argc, char *argv[]) mLinphoneThread = new Thread(this); init(); - lInfo() << QStringLiteral("Starting application " APPLICATION_NAME " (bin: " EXECUTABLE_NAME - "). Version:%1 Os:%2 Qt:%3") + lInfo() << QStringLiteral("Starting application %1 %2 %3 %4") + .arg(APPLICATION_NAME) + .arg("(bin:") + .arg(EXECUTABLE_NAME) + .arg("). Version:%1 Os:%2 Qt:%3") .arg(applicationVersion()) .arg(Utils::getOsProduct()) .arg(qVersion()); @@ -666,6 +669,17 @@ void App::initCore() { QMetaObject::invokeMethod(App::getInstance()->thread(), [this, settings] { // Initialize DestopTools here to have logs into files in case of errors. DesktopTools::init(); + + // CrashReporter must be call after app initialization like names. +#ifdef HAVE_CRASH_HANDLER + lInfo() << log().arg("Start CrashReporter."); + bool status = CrashReporter::start(); + if (!status) { + lWarning() << log().arg("CrashReporter could not start."); + } +#else + lWarning() << "[Main] The application doesn't support the CrashReporter."; +#endif // QML mEngine = new QQmlApplicationEngine(this); assert(mEngine); diff --git a/Linphone/core/path/Paths.cpp b/Linphone/core/path/Paths.cpp index 816cf19d9..33449dc3b 100644 --- a/Linphone/core/path/Paths.cpp +++ b/Linphone/core/path/Paths.cpp @@ -286,6 +286,15 @@ QString Paths::getCrashpadDirPath() { #endif } +QString Paths::getCrashpadAttachmentsPath() { +#ifdef HAVE_CRASH_HANDLER + return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + + Constants::PathCrashpadAttachments); +#else + return ""; +#endif +} + QString Paths::getMetricsDirPath() { return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathMetrics); diff --git a/Linphone/core/path/Paths.hpp b/Linphone/core/path/Paths.hpp index 9509db6f8..909ba4a7b 100644 --- a/Linphone/core/path/Paths.hpp +++ b/Linphone/core/path/Paths.hpp @@ -49,6 +49,7 @@ QString getFriendsListFilePath(); QString getLimeDatabasePath(); QString getLogsDirPath(); QString getCrashpadDirPath(); +QString getCrashpadAttachmentsPath(); QString getMetricsDirPath(); QString getMessageHistoryFilePath(); QString getPackageMsPluginsDirPath(); diff --git a/Linphone/tool/Constants.hpp b/Linphone/tool/Constants.hpp index 0a1514ef0..c9f858a4d 100644 --- a/Linphone/tool/Constants.hpp +++ b/Linphone/tool/Constants.hpp @@ -157,8 +157,9 @@ public: static constexpr char PathUserCertificates[] = "/usr-crt/"; #ifdef HAVE_CRASH_HANDLER static constexpr char PathCrashpad[] = "/crashpad/"; + static constexpr char PathCrashpadAttachments[] = "/crashpad/attachments/"; static constexpr char PathCrashpadHandler[] = CRASHPAD_EXECUTABLE_NAME; - static constexpr char BugsplatUrl[] = "https://Linphone.bugsplat.com/post/bp/crash/crashpad.php"; + static constexpr char BugsplatUrl[] = "https://" BUGSPLAT_DATABASE ".bugsplat.com/post/bp/crash/crashpad.php"; #endif static constexpr char PathCallHistoryList[] = "/call-history.db"; diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index 170107ef6..3a9b765d7 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -39,6 +39,7 @@ #include "tool/providers/AvatarProvider.hpp" #include +#include #include #include @@ -2260,3 +2261,9 @@ bool Utils::stringMatchFormat(QString toMatch, QRegularExpression regExp) { auto match = regExp.match(toMatch); return match.hasMatch(); } + +// Debug +void Utils::forceCrash() { + lInfo() << "throwing segmentation fault for debug"; + raise(SIGSEGV); +} \ No newline at end of file diff --git a/Linphone/tool/Utils.hpp b/Linphone/tool/Utils.hpp index 9b652f420..3c891add3 100644 --- a/Linphone/tool/Utils.hpp +++ b/Linphone/tool/Utils.hpp @@ -194,6 +194,9 @@ public: Q_INVOKABLE static bool stringMatchFormat(QString toMatch, QRegularExpression regExp); + // Debug + Q_INVOKABLE static void forceCrash(); + // QDir findDirectoryByName(QString startPath, QString name); static QString getApplicationProduct(); diff --git a/Linphone/tool/crash_reporter/CrashReporter.cpp b/Linphone/tool/crash_reporter/CrashReporter.cpp index 7a5a6ed9e..e39347efb 100644 --- a/Linphone/tool/crash_reporter/CrashReporter.cpp +++ b/Linphone/tool/crash_reporter/CrashReporter.cpp @@ -58,13 +58,24 @@ CrashReporter::CrashReporter(QObject *parent) : QObject(parent) { mAttachments.push_back(base::FilePath(Utils::getNativeString(logFiles + "2.log"))); } -void CrashReporter::start() { +bool CrashReporter::start() { + lInfo() << "[CrashReporter] Starting CrashReporter"; auto config = linphone::Factory::get()->createConfig(Utils::appStringToCoreString(Paths::getConfigFilePath("", true))); - CrashReporter::enable(SettingsModel::getCrashReporterEnabled(config)); + return CrashReporter::enable(SettingsModel::getCrashReporterEnabled(config)); } -void CrashReporter::run() { +bool CrashReporter::run() { + + // Attachments to be uploaded alongside the crash - default bundle size limit is 20MB + base::FilePath attachment(Utils::getNativeString(Paths::getCrashpadAttachmentsPath())); +#if defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) + // Crashpad hasn't implemented attachments on OS X yet + mAttachments.push_back(attachment); +#endif + lInfo() << "[CrashReporter] Start handler, handler path =" << Paths::getCrashpadHandlerFilePath() + << "| database path =" << Paths::getCrashpadDirPath() << "| metrics path =" << Paths::getMetricsDirPath() + << "bugsplat url =" << mBugsplatUrl; // crashpad::CrashpadClient *client = new crashpad::CrashpadClient(); bool status = mClient.StartHandler(mHandlerPath, mDatabasePath, mMetricsPath, mBugsplatUrl.toStdString(), mAnnotations.toStdMap(), mArguments, true, true, mAttachments); @@ -72,20 +83,33 @@ void CrashReporter::run() { if (!status) { lWarning() << "[CrashReporter] Failed to start Crashpad handler. Crashes will not be logged."; } else { - lInfo() << "[CrashReporter] Started Crashpad handler. Database at " << Paths::getCrashpadDirPath(); + lInfo() << "[CrashReporter] Started Crashpad handler. Database at" << Paths::getCrashpadDirPath(); + lInfo() << "[CrashReporter] Crashes upload url :" << mBugsplatUrl; } + return status; } -void CrashReporter::enable(const bool &on) { +bool CrashReporter::enable(const bool &on) { if (!gHandler) gHandler = new CrashReporter(); + lInfo() << "[CrashReporter] Enable CrashReporter" << on; std::unique_ptr database = crashpad::CrashReportDatabase::Initialize(gHandler->mDatabasePath); - if (database == NULL) return; + if (database == NULL) { + lInfo() << "[CrashReporter] No Crashpad database, return"; + return false; + } crashpad::Settings *settings = database->GetSettings(); - if (settings == NULL) return; + if (settings == NULL) { + lInfo() << "[CrashReporter] No Crashpad settings, return"; + return false; + } settings->SetUploadsEnabled(on); - if (on) gHandler->run(); - else { + + if (on) { + lInfo() << "[CrashReporter] Run Crashpad"; + return gHandler->run(); + } else { lInfo() << "[CrashReporter] Crashpad has been deactivated by user."; + return false; } } diff --git a/Linphone/tool/crash_reporter/CrashReporter.hpp b/Linphone/tool/crash_reporter/CrashReporter.hpp index f40ac99bc..42a02d4f1 100644 --- a/Linphone/tool/crash_reporter/CrashReporter.hpp +++ b/Linphone/tool/crash_reporter/CrashReporter.hpp @@ -33,9 +33,9 @@ class CrashReporter : public QObject { public: CrashReporter(QObject *parent = nullptr); - static void start(); - static void enable(const bool &on); - void run(); + static bool start(); + static bool enable(const bool &on); + bool run(); crashpad::CrashpadClient mClient; std::vector mAttachments; @@ -49,4 +49,4 @@ public: static CrashReporter *gHandler; }; -#endif \ No newline at end of file +#endif diff --git a/Linphone/view/Page/Layout/Main/MainLayout.qml b/Linphone/view/Page/Layout/Main/MainLayout.qml index 6a5cc6b18..e108ff40c 100644 --- a/Linphone/view/Page/Layout/Main/MainLayout.qml +++ b/Linphone/view/Page/Layout/Main/MainLayout.qml @@ -568,6 +568,23 @@ Item { } } } + + MouseArea { + z: parent.z + 1 + anchors.fill: parent + acceptedButtons: Qt.RightButton + onPressAndHold: (mouse) => { + debugPopup.open() + } + PopupButton { + id: debugPopup + visible: false + popup.contentItem: Button { + text: "debug: force crash" + onClicked: UtilsCpp.forceCrash() + } + } + } } } } diff --git a/cmake/install/install.cmake b/cmake/install/install.cmake index 7ce70906d..30c2c73aa 100644 --- a/cmake/install/install.cmake +++ b/cmake/install/install.cmake @@ -168,6 +168,8 @@ if(HAVE_CRASH_HANDLER) endif() endif() endif() +else() + message(DEBUG "No Crash handler, do not configure Crashpad") endif() # ==============================================================================