fix Windows crashes dump upload on BugSplat #LINQT-2384

Try to fix deploy (symbols are not uploaded in deploy, only packaging works with cr)

fix windows ci
This commit is contained in:
Gaelle Braud 2026-02-09 17:21:20 +01:00
parent 8442e37bc2
commit 5b4828aa56
13 changed files with 119 additions and 59 deletions

View file

@ -102,7 +102,7 @@ macosx-ninja-package:
- if: $PACKAGE_MACOSX - if: $PACKAGE_MACOSX
- if: $DEPLOY_MACOSX - if: $DEPLOY_MACOSX
variables: 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 RELEASE_FILE: -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$MACOSX_PLATFORM/$APP_FOLDER
extends: macosx-ninja extends: macosx-ninja
script: script:

View file

@ -181,21 +181,22 @@ win64-ninja-vs2022-scheduled-windows:
rules: rules:
- !reference [.rules-merge-request-manual, rules] - !reference [.rules-merge-request-manual, rules]
- if: $NIGHTLY_RELEASE - 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: $NIGHTLY_MASTER
- if: $DEPLOY_WINDOWS - if: $PACKAGE_WINDOWS
variables: 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 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 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: win64-ninja-vs2022-package-windows:
variables: variables:
CMAKE_GENERATOR: "Ninja" CMAKE_GENERATOR: "Ninja"
@ -207,15 +208,15 @@ win64-ninja-vs2022-package-windows:
- .vs-win64-package - .vs-win64-package
#Packaging for deployment (Upload symbols at the same time of the packaging) #Packaging for deployment (Upload symbols at the same time of the packaging)
win64-ninja-vs2022-package-cr-windows: # win64-ninja-vs2022-package-cr-windows:
variables: # variables:
CMAKE_GENERATOR: "Ninja" # CMAKE_GENERATOR: "Ninja"
CMAKE_ARCHITECTURE: "" # CMAKE_ARCHITECTURE: ""
PARALLEL_OPTIONS: "" # PARALLEL_OPTIONS: ""
extends: # extends:
- .windows-vs2022 # - .windows-vs2022
- .windows-ninja-variables # - .windows-ninja-variables
- .vs-win64-package-cr # - .vs-win64-package-cr
################################################# #################################################
@ -244,28 +245,6 @@ win64-codesigning:
when: always when: always
expire_in: 1 week 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 # DEPLOY
################################################# #################################################
@ -286,7 +265,7 @@ win64-ninja-vs2022-upload:
extends: extends:
- .win64-upload - .win64-upload
needs: needs:
- win64-codesigning-cr - win64-codesigning
.win64-plugins-upload: .win64-plugins-upload:
stage: deploy stage: deploy

View file

@ -244,7 +244,10 @@ if(NOT APPLE OR MONO_ARCH)
add_external() add_external()
endif() endif()
if(TARGET Crashpad) if(TARGET Crashpad)
message(DEBUG "Target Crashpad, enable crash handler")
set(HAVE_CRASH_HANDLER 1) set(HAVE_CRASH_HANDLER 1)
else()
message(DEBUG "Target is not Crashpad, disable crash handler")
endif() endif()
function(add_linphone_app) function(add_linphone_app)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) # Prevent project from overriding the options we just set here set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) # Prevent project from overriding the options we just set here

View file

@ -314,8 +314,11 @@ App::App(int &argc, char *argv[])
mLinphoneThread = new Thread(this); mLinphoneThread = new Thread(this);
init(); init();
lInfo() << QStringLiteral("Starting application " APPLICATION_NAME " (bin: " EXECUTABLE_NAME lInfo() << QStringLiteral("Starting application %1 %2 %3 %4")
"). Version:%1 Os:%2 Qt:%3") .arg(APPLICATION_NAME)
.arg("(bin:")
.arg(EXECUTABLE_NAME)
.arg("). Version:%1 Os:%2 Qt:%3")
.arg(applicationVersion()) .arg(applicationVersion())
.arg(Utils::getOsProduct()) .arg(Utils::getOsProduct())
.arg(qVersion()); .arg(qVersion());
@ -666,6 +669,17 @@ void App::initCore() {
QMetaObject::invokeMethod(App::getInstance()->thread(), [this, settings] { QMetaObject::invokeMethod(App::getInstance()->thread(), [this, settings] {
// Initialize DestopTools here to have logs into files in case of errors. // Initialize DestopTools here to have logs into files in case of errors.
DesktopTools::init(); 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 // QML
mEngine = new QQmlApplicationEngine(this); mEngine = new QQmlApplicationEngine(this);
assert(mEngine); assert(mEngine);

View file

@ -286,6 +286,15 @@ QString Paths::getCrashpadDirPath() {
#endif #endif
} }
QString Paths::getCrashpadAttachmentsPath() {
#ifdef HAVE_CRASH_HANDLER
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +
Constants::PathCrashpadAttachments);
#else
return "";
#endif
}
QString Paths::getMetricsDirPath() { QString Paths::getMetricsDirPath() {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +
Constants::PathMetrics); Constants::PathMetrics);

View file

@ -49,6 +49,7 @@ QString getFriendsListFilePath();
QString getLimeDatabasePath(); QString getLimeDatabasePath();
QString getLogsDirPath(); QString getLogsDirPath();
QString getCrashpadDirPath(); QString getCrashpadDirPath();
QString getCrashpadAttachmentsPath();
QString getMetricsDirPath(); QString getMetricsDirPath();
QString getMessageHistoryFilePath(); QString getMessageHistoryFilePath();
QString getPackageMsPluginsDirPath(); QString getPackageMsPluginsDirPath();

View file

@ -157,8 +157,9 @@ public:
static constexpr char PathUserCertificates[] = "/usr-crt/"; static constexpr char PathUserCertificates[] = "/usr-crt/";
#ifdef HAVE_CRASH_HANDLER #ifdef HAVE_CRASH_HANDLER
static constexpr char PathCrashpad[] = "/crashpad/"; static constexpr char PathCrashpad[] = "/crashpad/";
static constexpr char PathCrashpadAttachments[] = "/crashpad/attachments/";
static constexpr char PathCrashpadHandler[] = CRASHPAD_EXECUTABLE_NAME; 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 #endif
static constexpr char PathCallHistoryList[] = "/call-history.db"; static constexpr char PathCallHistoryList[] = "/call-history.db";

View file

@ -39,6 +39,7 @@
#include "tool/providers/AvatarProvider.hpp" #include "tool/providers/AvatarProvider.hpp"
#include <limits.h> #include <limits.h>
#include <signal.h>
#include <QClipboard> #include <QClipboard>
#include <QCryptographicHash> #include <QCryptographicHash>
@ -2260,3 +2261,9 @@ bool Utils::stringMatchFormat(QString toMatch, QRegularExpression regExp) {
auto match = regExp.match(toMatch); auto match = regExp.match(toMatch);
return match.hasMatch(); return match.hasMatch();
} }
// Debug
void Utils::forceCrash() {
lInfo() << "throwing segmentation fault for debug";
raise(SIGSEGV);
}

View file

@ -194,6 +194,9 @@ public:
Q_INVOKABLE static bool stringMatchFormat(QString toMatch, QRegularExpression regExp); Q_INVOKABLE static bool stringMatchFormat(QString toMatch, QRegularExpression regExp);
// Debug
Q_INVOKABLE static void forceCrash();
// QDir findDirectoryByName(QString startPath, QString name); // QDir findDirectoryByName(QString startPath, QString name);
static QString getApplicationProduct(); static QString getApplicationProduct();

View file

@ -58,13 +58,24 @@ CrashReporter::CrashReporter(QObject *parent) : QObject(parent) {
mAttachments.push_back(base::FilePath(Utils::getNativeString(logFiles + "2.log"))); mAttachments.push_back(base::FilePath(Utils::getNativeString(logFiles + "2.log")));
} }
void CrashReporter::start() { bool CrashReporter::start() {
lInfo() << "[CrashReporter] Starting CrashReporter";
auto config = auto config =
linphone::Factory::get()->createConfig(Utils::appStringToCoreString(Paths::getConfigFilePath("", true))); 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(); // crashpad::CrashpadClient *client = new crashpad::CrashpadClient();
bool status = mClient.StartHandler(mHandlerPath, mDatabasePath, mMetricsPath, mBugsplatUrl.toStdString(), bool status = mClient.StartHandler(mHandlerPath, mDatabasePath, mMetricsPath, mBugsplatUrl.toStdString(),
mAnnotations.toStdMap(), mArguments, true, true, mAttachments); mAnnotations.toStdMap(), mArguments, true, true, mAttachments);
@ -73,19 +84,32 @@ void CrashReporter::run() {
lWarning() << "[CrashReporter] Failed to start Crashpad handler. Crashes will not be logged."; lWarning() << "[CrashReporter] Failed to start Crashpad handler. Crashes will not be logged.";
} else { } 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(); if (!gHandler) gHandler = new CrashReporter();
lInfo() << "[CrashReporter] Enable CrashReporter" << on;
std::unique_ptr<crashpad::CrashReportDatabase> database = std::unique_ptr<crashpad::CrashReportDatabase> database =
crashpad::CrashReportDatabase::Initialize(gHandler->mDatabasePath); 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(); crashpad::Settings *settings = database->GetSettings();
if (settings == NULL) return; if (settings == NULL) {
lInfo() << "[CrashReporter] No Crashpad settings, return";
return false;
}
settings->SetUploadsEnabled(on); 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."; lInfo() << "[CrashReporter] Crashpad has been deactivated by user.";
return false;
} }
} }

View file

@ -33,9 +33,9 @@ class CrashReporter : public QObject {
public: public:
CrashReporter(QObject *parent = nullptr); CrashReporter(QObject *parent = nullptr);
static void start(); static bool start();
static void enable(const bool &on); static bool enable(const bool &on);
void run(); bool run();
crashpad::CrashpadClient mClient; crashpad::CrashpadClient mClient;
std::vector<base::FilePath> mAttachments; std::vector<base::FilePath> mAttachments;

View file

@ -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()
}
}
}
} }
} }
} }

View file

@ -168,6 +168,8 @@ if(HAVE_CRASH_HANDLER)
endif() endif()
endif() endif()
endif() endif()
else()
message(DEBUG "No Crash handler, do not configure Crashpad")
endif() endif()
# ============================================================================== # ==============================================================================