mirror of
https://github.com/Mudlet/Mudlet
synced 2026-08-13 18:26:27 -04:00
#### Brief overview of PR changes/additions When Mudlet crashes on Windows, it sends a crash report to Sentry. Until now those reports were unusable: instead of showing where in Mudlet the problem happened, they only listed anonymous system files. This PR fixes the Windows build so each crash report points at the actual place in Mudlet that crashed. #### Motivation for adding to Mudlet Every recent Windows crash in Sentry was a dead end — we could see that Mudlet crashed, but not *where*, so none of them could be investigated or fixed. The crash details we were uploading didn't match the version of Mudlet people were actually running, so Sentry could never line them up. This makes Windows crash reports actionable again. #### Other info (issues closed, discussion etc) Needs to be verified on a nightly/tagged CI build: the uploaded debug file should match the shipped `mudlet.exe`, and a fresh crash should show Mudlet function names. No change for users beyond more useful crash reports; the new debug file is only sent to Sentry, never shipped.
182 lines
7.4 KiB
Bash
182 lines
7.4 KiB
Bash
#!/bin/bash
|
|
###########################################################################
|
|
# Copyright (C) 2025 by Nicolas Keita - nicolaskeita2@gmail.com #
|
|
# #
|
|
# This program is free software; you can redistribute it and/or modify #
|
|
# it under the terms of the GNU General Public License as published by #
|
|
# the Free Software Foundation; either version 2 of the License, or #
|
|
# (at your option) any later version. #
|
|
# #
|
|
# This program is distributed in the hope that it will be useful, #
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
# GNU General Public License for more details. #
|
|
# #
|
|
# You should have received a copy of the GNU General Public License #
|
|
# along with this program; if not, write to the #
|
|
# Free Software Foundation, Inc., #
|
|
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
|
|
###########################################################################
|
|
|
|
set -e
|
|
|
|
SENTRY_CLI_VERSION="3.6.0"
|
|
|
|
download_sentry_cli() {
|
|
local os="$1"
|
|
local arch="$2"
|
|
local file="$3"
|
|
local url=""
|
|
local base="https://github.com/getsentry/sentry-cli/releases/download/${SENTRY_CLI_VERSION}"
|
|
|
|
if [[ "$os" == "Darwin" ]]; then
|
|
if [[ "$arch" == "x86_64" ]]; then
|
|
url="${base}/sentry-cli-Darwin-x86_64"
|
|
elif [[ "$arch" == "arm64" ]]; then
|
|
url="${base}/sentry-cli-Darwin-arm64"
|
|
fi
|
|
elif [[ "$os" == "Linux" ]]; then
|
|
if [[ "$arch" == "x86_64" ]]; then
|
|
url="${base}/sentry-cli-Linux-x86_64"
|
|
fi
|
|
elif [[ "$os" == "MINGW"* || "$os" == "MSYS"* || "$os" == "CYGWIN"* ]]; then
|
|
if [[ "$arch" == "x86_64" ]]; then
|
|
url="${base}/sentry-cli-Windows-x86_64.exe"
|
|
elif [[ "$arch" == "i686" || "$arch" == "i386" ]]; then
|
|
url="${base}/sentry-cli-Windows-i686.exe"
|
|
fi
|
|
fi
|
|
|
|
if [[ -z "$url" ]]; then
|
|
echo "Unsupported OS/ARCH: $os / $arch"
|
|
return 1
|
|
fi
|
|
|
|
echo "Downloading $url ..."
|
|
curl -L -o "$file" "$url"
|
|
|
|
if [[ "$os" != "MINGW"* && "$os" != "MSYS"* && "$os" != "CYGWIN"* ]]; then
|
|
chmod +x "$file"
|
|
fi
|
|
echo "$file ready"
|
|
}
|
|
|
|
|
|
if [ -z "$SENTRY_AUTH_TOKEN" ]; then
|
|
echo "[Sentry_upload_debug_files] Missing environment variable: SENTRY_AUTH_TOKEN. Therefore, the debug file upload to sentry.io is canceled."
|
|
exit 0
|
|
fi
|
|
|
|
if [ -z "$1" ]; then
|
|
echo "Usage: $0 <path-to-mudlet-executable>"
|
|
echo "Please provide the path to the Mudlet executable as an argument."
|
|
exit 1
|
|
fi
|
|
|
|
MUDLET_EXEC="$(realpath "$1")"
|
|
if [ ! -f "$MUDLET_EXEC" ]; then
|
|
echo "Error: Mudlet executable not found at $MUDLET_EXEC"
|
|
exit 1
|
|
fi
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
OS="$(uname -s)"
|
|
ARCH="$(uname -m)"
|
|
|
|
download_sentry_cli "$OS" "$ARCH" "sentry-cli"
|
|
./sentry-cli login --auth-token "$SENTRY_AUTH_TOKEN"
|
|
|
|
FILES_TO_UPLOAD=("$MUDLET_EXEC")
|
|
if [[ "$OS" == "Linux" ]]; then
|
|
DEBUG_FILE="${MUDLET_EXEC}.debug"
|
|
[[ -f "$DEBUG_FILE" ]] && FILES_TO_UPLOAD+=("$DEBUG_FILE")
|
|
elif [[ "$OS" == "Darwin" ]]; then
|
|
DEBUG_FILE="${MUDLET_EXEC}.dSYM"
|
|
[[ -d "$DEBUG_FILE" ]] && FILES_TO_UPLOAD+=("$DEBUG_FILE")
|
|
elif [[ "$OS" == "MINGW"* ]]; then
|
|
# The PDB shares its debug-id with the shipped mudlet.exe, so uploading both
|
|
# lets Sentry match crash minidumps and symbolicate them (see WithSentry.cmake).
|
|
# The PDB is expected on every Windows sentry build, so fail loudly if it is
|
|
# missing rather than silently uploading only the exe (which would revert to
|
|
# unsymbolicated crash reports if the --pdb link flag is ever lost).
|
|
PDB_FILE="${MUDLET_EXEC%.exe}.pdb"
|
|
if [[ -f "$PDB_FILE" ]]; then
|
|
FILES_TO_UPLOAD+=("$PDB_FILE")
|
|
else
|
|
echo "error: expected PDB at $PDB_FILE not found - Windows crash reports would be unsymbolicated"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
for f in "${FILES_TO_UPLOAD[@]}"; do
|
|
echo "Uploading $f to Sentry..."
|
|
./sentry-cli debug-files upload "$f" --project "mudlet"
|
|
done
|
|
|
|
# Qt ships its debug info as separate DWARF ".debug" companions; sentry-cli 3.5.0+
|
|
# parses these, so upload them too. See https://github.com/getsentry/sentry/issues/104738
|
|
if [[ -n "$MSYSTEM" && -n "$MSYSTEM_PREFIX" ]]; then
|
|
MINGW_BIN="${MSYSTEM_PREFIX}/bin"
|
|
QT_PLUGINS_DIR="${MSYSTEM_PREFIX}/share/qt6/plugins"
|
|
|
|
echo ""
|
|
echo "=== Collecting Qt DWARF debug companions for Sentry ==="
|
|
|
|
DEBUG_FILES=()
|
|
|
|
# Upload .debug companions only for the Qt6 modules mudlet.exe actually depends
|
|
# on (walk its import table), not every Qt6 DLL in the bin.
|
|
if command -v objdump >/dev/null 2>&1; then
|
|
declare -A seen_dll=()
|
|
pending=("$MUDLET_EXEC")
|
|
# Runtime-loaded Qt plugins can pull in Qt modules that mudlet.exe does not
|
|
# link directly (e.g. the svg imageformat/iconengine plugins pull in Qt6Svg,
|
|
# which is not in our components list). Seed the walk with the plugin DLLs too
|
|
# so their imports get their .debug companions collected as well.
|
|
if [[ -d "$QT_PLUGINS_DIR" ]]; then
|
|
while IFS= read -r -d '' plugin_dll; do
|
|
pending+=("$plugin_dll")
|
|
done < <(find "$QT_PLUGINS_DIR" -type f -name '*.dll' -print0)
|
|
fi
|
|
while [[ ${#pending[@]} -gt 0 ]]; do
|
|
current="${pending[0]}"
|
|
pending=("${pending[@]:1}")
|
|
while IFS= read -r dll; do
|
|
[[ -z "$dll" || -n "${seen_dll[$dll]:-}" ]] && continue
|
|
seen_dll[$dll]=1
|
|
dll_path="$MINGW_BIN/$dll"
|
|
[[ -f "$dll_path" ]] || continue
|
|
pending+=("$dll_path")
|
|
if [[ "$dll" == Qt6*.dll ]]; then
|
|
# companion may be "<name>.dll.debug" or "<name>.debug"; add once
|
|
for debug_file in "$MINGW_BIN/${dll}.debug" "$MINGW_BIN/${dll%.dll}.debug"; do
|
|
[[ -f "$debug_file" && -z "${seen_dll[$debug_file]:-}" ]] && { seen_dll[$debug_file]=1; DEBUG_FILES+=("$debug_file"); }
|
|
done
|
|
fi
|
|
done < <(objdump -p "$current" 2>/dev/null | sed -n 's/^[[:space:]]*DLL Name:[[:space:]]*//p')
|
|
done
|
|
else
|
|
echo "objdump not found - falling back to uploading all Qt6 debug companions"
|
|
for debug_file in "$MINGW_BIN"/Qt6*.debug; do
|
|
[[ -f "$debug_file" ]] && DEBUG_FILES+=("$debug_file")
|
|
done
|
|
fi
|
|
|
|
# Qt plugins (image formats, platforms, tls, ...) can appear in crash stack
|
|
# traces too, so upload every plugin companion we can find
|
|
if [[ -d "$QT_PLUGINS_DIR" ]]; then
|
|
while IFS= read -r -d '' debug_file; do
|
|
DEBUG_FILES+=("$debug_file")
|
|
done < <(find "$QT_PLUGINS_DIR" -type f -name '*.debug' -print0)
|
|
fi
|
|
|
|
if [[ ${#DEBUG_FILES[@]} -gt 0 ]]; then
|
|
echo "Uploading ${#DEBUG_FILES[@]} Qt debug companion files to Sentry..."
|
|
./sentry-cli debug-files upload "${DEBUG_FILES[@]}" --project "mudlet"
|
|
echo "Qt debug symbols uploaded successfully"
|
|
else
|
|
echo "No Qt .debug files found - are the qt6-*-debug packages installed?"
|
|
fi
|
|
fi
|
|
|
|
rm -f sentry-cli
|