Nous allons voir dans cet article comment mettre en place un système de crash report dans votre programme C++. Il vous génèrera un fichier zip avec un dump (utilisable dans Visual Studio) et vous pourrez même y intégrer vos logs. Cependant, je ne vais discuter que de Windows (Win32) et pas de Linux / MacOS. Plus précisement de BugTrap qui est, d’après moi, le meilleur pour cette plateforme. À noter qu’il existe des alternatives comme Breakpad ou Crashpad, qui sont cross-plateforme, mais qui manquent d’une “interface” pour indiquer à l’utilisateur final qu’il y a eu un problème.
Tout d’abord, qu’est-ce que BugTrap ?
BugTrap is a tool to catch unhandled exceptions in unmanaged and managed .NET code. BugTrap also supports sending crash reports to a remote server for analysis.
BugTrap est un outil conçu pour capturer les exceptions non gérées dans les codes gérés (C# / .NET) et non gérés (C++). Il prend également en charge l’envoie de rapports de plantage à un serveur distant pour analyse. BugTrap vous offre un moyen unique de collecter et de visualiser automatiquement les exceptions générées dans tous vos logiciels. Facile à installer et à utiliser, BugTrap collectera automatiquement et agrégera les exceptions non gérées de toutes vos différentes applications en un seul endroit. Cela vous permet de trouver des bugs dans votre logiciel.
L’avantage de BugTrap par rapport à d’autres solutions c’est qu’il possède une interface qui indique à l’utilisateur final que quelque chose c’est mal passé. Et que l’envoie du crash report est OPTIONNEL (pour le RGPD et par principe). Voici quelques images (tirées du Github de BugTrap):
Compilation
Première étape, vous devez clone le dépôt de BugTrap pour le compiler avec Visual Studio, vous devriez savoir faire:
git clone https://github.com/Brouilles/BugTrap.git
Pour le moment, je vous recommande l’utilisation de mon fork (qui est en PR) qui ajoute le support de Visual Studio 2019 et 2022. Mais le dépôt officiel est disponible à cette adresse https://github.com/bchavez/BugTrap.
À partir de maintenant, c’est assez simple, dans le dossier nouvellement créé, allez dans “source” puis ouvrez le projet, pour moi ça sera BugTrap.vs2022.sln
.
À noter qu’il vous faut dans Visual Studio Installer la charge de travail “Développement Desktop C++”. Ainsi que dans les composants individuels C++ MFC pour la dernière version de Build Tools v143 (x86 & x64)
. Afin de pouvoir compiler BugTrap.
Comme vous pouvez le voir, plusieurs versions de BugTrap sont compilables. À vous de voir la version qui correspond à votre besoin. En général c’est la version Unicode qui est préférable.
Puis clic droit sur le projet dans l’explorateur de Visual Studio et “Build”.
Vous retrouverez la DLL que vous venez de générer dans le dossier BugTrap/bin/
. BugTrapU-x64
le U est pour Unicode (si vous utilisez cette version).
Intégration dans un programme
Maintenant, il vous suffit de configurer votre projet correctement. C’est-à-dire:
- Copier les headers et le dossier bin de BugTrap dans un dossier dans votre projet (exemple ThirdParty).
- Configurer correctement
Additional Include Directories
dans votre projet. - Mettre
BugTrapU-x64.lib
dans le linker.
Et un code qui plante !
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <Tchar.h>
#include <BugTrap.h>
static void SetupExceptionHandler()
{
// Setup exception handler
BT_SetAppName(_T("BugTrap Console Test"));
BT_SetSupportEMail(_T("[email protected]"));
BT_SetFlags(BTF_DETAILEDMODE);
BT_SetSupportURL(_T("https://www.dezeiraud.com/"));
// required for VS 2005 & 2008
BT_InstallSehFilter();
}
int main()
{
SetupExceptionHandler();
std::cout << "Hello World!\n";
// Segfault
int* p = nullptr;
*p = 1;
std::cout << *p << std::endl;
}
Mais cela n’est pas tout. Malheureusement en l’état BugTrap détectera notre système d’exploitation comme Windows 8. Pour que Windows 10 et 11 soit correctement détecté, vous devez ajouter un fichier app.manifest
à la racine du projet. Avec le contenu suivant:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
name="YOURAPPNAME"
version="1.0.0.0"
type="win32" />
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 & 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>
Avec BT_SetFlags
vous pouvez même définir des flags supplémentaires afin, par exemple, d’intégrer un screenshot de votre application au moment du crash (BTF_SCREENCAPTURE
). Ou vos propres fichiers de logs dans l’archive finale. Je vous invite à lire la documentation pour voir les possibilités https://github.com/bchavez/BugTrap/blob/master/doc/BugTrap.pdf.
Maintenant, en démarrant l’application précédente en Release (avec une build en debug, BugTrap ne sera pas appelé). Elle devrait crash directement au lancement, avec la fenêtre de BugTrap. Nous allons sauvegarder le rapport d’erreur. Cliqué sur “more…” de la fenêtre de BugTrap, une nouvelle fenêtre s’ouvre puis Save.
Vous devriez avoir un zip avec le contenu suivant:
C’est votre rapport de crash. Le errorlog.xml
contient des informations sur la machine de l’utilisateur où votre application à crash (RAM, système d’exploitation, processeur, etc…) et le crashdump.dmp.
Vous pouvez ouvrir le errorlog.xml avec le projet CrashExplorer
présent dans le projet Visual Studio de BugTrap. C’est un outil à destination du développeur (vous) pour visualiser avec une interface les informations. Si vous n’êtes pas fan du XML.
Une fois le crashdump.dmp extrait, vous pouvez l’ouvrir avec Visual Studio (puis dans Actions à droite, Debug with Native Only). Attention, il vous faut la même version du code de votre projet que la version avec laquelle l’utilisateur a crash, se faisant, grâce au fichier .dmp, Visual Studio va vous indiquer où l’exception s’est produite dans votre code.
Avec les valeurs des variables associées à ce moment. À l’aide de ces informations, vous devriez avoir le nécessaire pour corriger le bug de votre programme et déployer une mise à jour !