Skip to content

Générer des crashdump (crash report) pour votre projet win32 / C++

Posted on:8 juin 2023 at 02:00

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):

BugTrap

BugTrap

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.

Visual Studio 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:

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:

BugTrap VS manifest

<?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.

Alt text

Vous devriez avoir un zip avec le contenu suivant:

Alt text

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.

Alt text

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 !