31 mars 2024
Ce document donne des précisions sur l’utilisation de différents outils utilisés durant CSC4526 :
Pour les premiers canevas de projet que vous utiliserez dans CSC4526, vous aurez juste à modifier des fichiers source déjà fournis dans le canevas.
Puis, vous serez amené·e à ajouter des fichiers sources, ce qui requiert une procédure particulière décrite ci-dessous :
.h
et de .cpp
. NB : CLion modifie
src/core/CMakeLists.txt
pour y ajouter le nom des fichiers
ajoutés.CMakeLists.txt
:
src/core
, puis cliquez gauche sur Ajouter > Ajouter un
nouvel élément… : une fenêtre “Ajouter un nouvel élément src”
s’ouvre.src/code
src/core/CMakeLists.txt
.Pour analyser les fuites mémoire dans du code C++, nous nous appuyons sur des outils dédiés.
Pour tester ces outils, vous pouvez vous appuyer sur votre propre projet ou bien créer un projet console et substituer le code automatiquement généré par le contenu de codeQuiFuit.cpp.
Pour éviter l’installation d’un autre outil, nous nous appuyons sur
le sanitizer
address
.
Pour ce faire, modifiez le CMakeLists.txt
à la racine de
votre projet en lui ajoutant les lignes :
.......
set (BUILD_SHARED_LIBS FALSE)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) # This cmake_policy avoids warning by cmake when we use pugixml
cmake_policy(SET CMP0135 NEW) # This cmake_policy avoids warning by cmake when we fetch contents based on URL
###### DEBUT lignes a rajouter
if(MSVC)
add_compile_options(/fsanitize=address)
else()
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
endif()
###### FIN lignes a rajouter
set(CMAKE_CXX_STANDARD 20)
.......
Dans votre projet, prenez en compte les changements de
CMakeLists.txt
, puis régénérez complètement votre
projet.
Si vous exécutez, comme jusqu’à présent, unitTests
dans
le cadre de l’environnement GoogleTest, vos tests sont toujours
tous corrects. Cependant, en bas à gauche de votre écran, à côté de
l’onglet Console
, il y a un onglet Sanitizers
qui vous signale des problèmes repérés dans votre code :
Pour information, si vous choisissez d’exécuter la cible
All CTests
, les tests qui causent la fuite mémoire sont
signalés comme ne passant pas (alors que, pourtant, les différents
EXPECT
ou ASSERT
sont corrects). L’onglet
Sanitizers
permet de comprendre les problèmes.
Leak-DefinitelyLost 3 Warnings
. Si vous
dépliez ce message, vous accédez au détail de ces fuites mémoire. En
dépliant l’une de ces fuites, vous avez accès à la pile d’appel qui a
amené à l’allocation mémoire sans libération associée. En
double-cliquant sur l’une des lignes de la pile d’appel (par exemple,
dans la figure 1, sur la ligne
Group::Group(pugi::xml_node) Group.cpp:15)
), vous accédez
au code de la ligne qui a fait le new
.Suivez la démarche proposée dans la section “CLion sans installation d’un autre outil” de Linux.
Sous MacOS, vous pouvez aussi vous appuyer sur l’outil leaks fourni en standard (cf. cet article).
Dans un terminal, compiler votre programme avec l’option
-g
(NB: Clion compile votre programme directement
avec cette option). Par exemple:
cc -g -Wall -Werror nomFichier.c -o nomFichier
leaks --atExit --list -- ./nomFichier
# ==> Détection des leaks sans voir leur emplacement précis dans le code
export MallocStackLogging=1
# Rien ne se passe
leaks --atExit --list -- ./nomFichier
# ==> Affichage des emplacements précis dans le code
Address
permette la détection de fuites
mémoire sous WindowsWindows implémente le sanitizer
Address
pour son compilateur MSVC (cf. tous
ces exemples de détection), mais, actuellement, cette implémentation
ne détecte pas les fuites mémoire !
Si vous le souhaitez, votez ici pour demander l’ajout de cette fonctionnalité !
En attendant, consultez la section suivante pour détecter les fuites mémoire sous Windows.
Par rapport à Valgrind sous Linux, le Visual Studio Profiler est un peu plus compliqué à mettre en oeuvre, mais présente l’avantage de ne pas du tout ralentir l’application profilée.
Cet outil étant disponible en standard dans Visual Studio, il n’y a aucune installation à faire.
Commencez par poser un point d’arrêt au niveau de l’appel à la
fonction que vous souhaitez tester. Par exemple, dans le cas d’une
application CSC4526, l’appel à la fonction myMain()
.
Si vous souhaitez voir si vos tests unitaires révèlent des fuites mémoire :
unitTests.exe!RUN_ALL_TESTS()
et double-cliquez dessus : le
code de gtest.h
s’affiche.return ::testing::UnitTest::GetInstance()->Run();
unitTests.exe!Circle[]
)
L’outil Dr. Memory est sensé être un équivalent de Valgrind sous Windows. Mais il ne fonctionne pas correctement. Nous le mentionnons ici seulement pour information.
TODO : A compléter.
Tous les canevas de projet C++ fournis dans le cadre de CSC4526 s’appuient sur cmake. cmake permet de configurer l’environnement du projet, ce qui dispensera de configurer l’IDE.
Commencez par lire ci-dessous les instructions communes à tous les IDE/OS, puis lisez la section correspondant à votre IDE/OS.
SampleSFML.zip
dans l’exercice d’introduction) dans le répertoire de votre choix.
C:\Users\Barnabé\Mes Documents\CPP
est à bannir à cause
du é dans Barnabé et de
l’espace dans Mes Documents ; il vaut mieux
que le chemin soit C:\CPP
. Si vous ne respectez pas ce
conseil, votre IDE risque de recompiler
systématiquement l’ensemble de votre projet.SampleSFML
)nouveau_nom_du_répertoire_racine\CMakeLists.txt
, au niveau
de la ligne
project(nom_projet VERSION 1.0.0 LANGUAGES CXX)
, remplacez
nom_projet
par un nom (sans espace) qui correspond à votre
projet.A titre d’information, voici les temps de chargement du dossier
(génération de la structure du projet) et de compilation/édition de lien
du projet observés en 2024-2025 avec SampleSFML.zip
,
donc SFML 3.0.0 :
Système d’exploitation | Temps de chargement du dossier
(cmake -B build ) |
Temps de compilation/édition de lien du
projet (cmake --build build ) |
---|---|---|
Linux Ubuntu 24.04 (Compilateur gcc ; sur WSL ; Processeur i7 à 2,80 Ghz, 32 Go de RAM) | 0’23” | 0’36” |
macOS 15.3 Sequoia (Compilateur Apple clang ; Processeur Intel 3.8 GHz et 128 Go RAM) | 0’31” | 1’02” |
Windows 11 (Compilateur MSVC ; Processeur i7 à 2,80 Ghz, 32 Go de RAM) | 2’04” | 1’01” |
chemin_absolu_vers_votre_projet/CMakeLists.txt
. Cliquez sur
“OK” : Une fenêtre “Open Project” apparaît. CLiquez sur “Open as
Project”sudo apt-get install -y ninja-build
(cf. ce
site).cd chemin_absolu_vers_votreRépertoireProjet
rm -Rf .idea build cmake-build-debug
cmake -B build
#
# Si cmake affiche l'une des messages suivants:
# - "cmake not found"
# - "Error during cmake"
# - "No CMAKE_CXX_COMPILER"
# - "Could NOT find X11"
# Alors tapez la commande suivante (qui est sur plusieurs lignes) :
#
sudo apt update && sudo apt install -y \
\
g++ \
cmake \
libxrandr-dev \
libxcursor-dev \
libxi-dev \
libudev-dev \
libflac-dev \
libvorbis-dev \
libgl1-mesa-dev \
libegl1-mesa-dev \
libdrm-dev \
libgbm-dev
libfreetype-dev# Au final, vous devriez obtenir le message "-- Build files have been written to: absolute_path_to_your_project". Cela signifie que toutes les installations préalables pour Linux sont OK.
#
# Il vous reste à nettoyer votre répertoire de votre test cmake:
rm -Rf build
SampleSFML
),
une fenêtre “SFML works !” semblable à la fenêtre ci-dessous
s’ouvre:Dans un terminal, tapez la commande which brew pour vous
assurer d’avoir la version de Homebrew adaptée à l’architecture
ARM de votre processeur : Si la version de Homebrew est adaptée
à ARM, le chemin affiché devrait commencer par
/opt/homebrew/
. Si le chemin affiché commence par
/usr/local/
, votre version de Homebrew est adaptée
à un processeur Intel (ce qui vous posera des soucis lorsque
CLion fera des éditions de liens) : Il vous faut installer un
Homebrew adapté à ARM (cf. procédure un peu modifiée de la 1ère
réponse ici) :
brew bundle dump
pour créer un Brewfile des
packages déjà installés.cd /opt
sudo mkdir -p homebrew
sudo chown -R $(whoami) homebrew
curl -L https://github.com/Homebrew/brew/tarball/master |\
tar xz --strip 1 -C homebrew
#+end_src
- Modifiez *PATH*
#+begin_src bash
PATH=/opt/homebrew/bin:$PATH
hash -d brew
brew bundle install --file /path/to/Brewfile
brew install ninja
(cf. ce site).brew install sfml
SampleSFML
),
une fenêtre “SFML works !” semblable à la fenêtre ci-dessous
s’ouvre:SampleSFML
,
la fenêtre suivante s’affiche pour vous signifier que SFML
fonctionne.Pour information, cette procédure crée les répertoires .vs et out dans le répertoire de votre projet.
TODO : A compléter.
Cette section retranscrit le contenu des vidéos de tutoriel sur le débogage :
Ces vidéos utilisent le fichier ExempleDeDebugDeProgramme.cpp
Les manipulations ont été effectuées en s’appuyant sur le scénario
Visual Studio ci-dessous. Pour information, CLion ne
permet pas de mettre en place un arrêt quand la valeur d’une variable
change (il faut taper manuellement la commande gdb
watch
dans la console gdb fournie par
CLion).
Dans ce tutoriel vidéo, je vous propose une initiation aux principales fonctions de débogage offertes par Visual Studio. Vous pourrez ainsi gagner en efficacité et en rapidité dans la mise au point de vos programmes, qu’ils soient écrits en C++ ou dans d’autres langages. En effet, les notions présentées ici sont génériques à tous les langages de programmation.
Notez que, pour ce tutoriel, nous nous appuierons sur le fichier
ExempleDeDebugDeProgramme.cpp
que je vous invite à
télécharger maintenant, si vous ne l’avez pas déjà fait.
Expression: vector subscript out of range
Please retry to debug the application
, clic sur
Recommencer
Expression: vector subscript out of range
.Please retry to debug the application
, clic sur
Recommencer
vector subscript out of range
v.size
: VS vous affiche 4.v
et cliquez sur la flèche pour voir le
contenu de v
: il y a 4 éléments. NB : on peut aussi voir
le contenu de v
dans le cadre des variables locales en bas
à gauche.-1
et cliquons
sur le bouton “Redémarrer”division par zéro
. Effectivement c
vaut
0
(qui ne fait pas bon ménage avec l’opérateur
modulo).c
s’est retrouvé avec la valeur
0
, mettons un point d’arrêt au niveau de la définition de
c
, puis exécutons pas à pas le programme.unCalcul()
) ==> Zut, la valeur de c
a
changé.unCalcul()
unCalcul()
return resultat
resultat == 0
c
soit
définie.c
et “Arrêtez quand la valeur change”. Notez que la variable
a
change aussi de couleur (vu que c
est une
référence vers a
).a
(et donc
c
) change.c
: il faut programmer un nouveau
point d’arrêt pour cette variable.Nous voici arrivés à la fin de cette initiation au débogage sous Visual Studio : n’hésitez pas à faire vos propres expériences pour vous familiariser avec cet outil et ainsi gagner en efficacité et en rapidité dans la mise au point de vos programmes.
TODO : A compléter.
La version Release d’un programme est une version sans information de debug, donc plus rapide à l’exécution. Cette section décrit comment la générer :
main | Release
.x64-Debug
et sélectionnez
Gérer les configurations
: Un onglet
CMakeSettings.json
s’ouvre.Configurations
, cliquer sur le
bouton “+” et sélectionnez x64-Release
/CMakeSettings.json
(et
enregistrez-le).x64-Release
à la
place de x64-Debug
: Votre projet est généré en mode
Release/Google Test est un environnement facilitant l’écriture et le passage de tests unitaires. Cette section présente l’utilisation de Google Test selon l’IDE que vous utilisez. Nous supposons ici que vous avez déjà appliqué cmake sur un canevas de projet contenant des tests unitaires.
Si cette fenêtre ne vous affiche aucun test, mais le message
“Générez votre solution pour découvrir tous les tests disponibles”,
vérifiez que votre CMakeLists.txt
racine contient les trois
dernières lignes suivantes :
include(GoogleTest)
enable_testing()
add_subdirectory(src/tests)
Si la ligne include(GoogleTest)
manque, ajoutez-la
et supprimez-la du fichier unitTests/CMakeLists.txt
où elle
doit encore apparaître.
Si elle ne manque pas, régénérez tout votre projet (Menu Projet > Supprimer le cache et reconfigurer) avec la fenêtre “Explorateur de test” ouverte.
Si cette fenêtre “Explorateur de tests” n’affiche toujours pas vos tests, prévenez Michel Simatic pour qu’il voit ce qui peut être fait (Ce ticket ne serait pas corrigé).
unitTests (1)
: vous avez passé votre premier test
unitaire sur votre application.unitTest (1)
et double-cliquez sur la ligne
terminale TestName
: Visual Studio ouvre le
fichier unitTests.cpp
au niveau du test unitaire en erreur
(et l’explorateur de tests explicite l’erreur dans la sous-fenêtre à
droite “Récapitulatif des détails du test”)TODO : A compléter.
Le profileur de performances permet de repérer les sections de code où votre programme passe du temps.
main_optimise.exe
) et OK.S106: Replace this usage of std::cout by a logger
qui est
trop complexe à résoudre pour nos applications “jouet”), cliquez droit
sur la règle (dans la fenêtre d’erreur de VisualStudio ou pour
CLion, dans la sous-fenêtre SonarQube) et sélectionnez
“Disable SonarQube rule”.Pour la session CSC4526 2023-2024, un bug lié à la combinaison Visual Studio version 17.9.6 / cmake / SonarQube est apparu quelques jours avant le début de ce cours. Il empêche que SonarQube affiche ses messages dans Visual Studio.
Voyons tout d’abord si vous êtes concerné·e par ce bug :
Dans Visual Studio, Outils > Ligne de commande > PowerShell développeur : Une fenêtre PowerShell s’ouvre.
Tapez la commande cmake --version
: La version de
cmake
s’affiche.
Si la version affichée est
cmake version 3.28.0-msvc1
, vous êtes concerné·e par le
bug, ce qui explique que vous avez peut-être vu le message
SonarQube: Failed to analyze <nomFichier>. See the Output Window for more information
(en bas à gauche).
D’ailleurs, dans l’onglet “Sortie” en bas de l’écran, si vous sélectionnez “SonarQube” à la place de “CMake” dans la combo box “Afficher la sortie à partir de :”, vous voyez le message :
[CLangAnalyzer] Analyzing C:\temp\CSC4526\SampleGoogleTest\unitTests\unitTests.cpp
[CFamily Analysis] Unsupported configuration: Unexpanded response file is not supported:@unitTests\CMakeFiles\unitTests.dir\unitTests.cpp.obj.modmap.
[CLangAnalyzer] Failed to analyze C:\temp\CSC4526\SampleGoogleTest\unitTests\unitTests.cpp: See above for more information.
Cet article indique la démarche pour résoudre ce bug :
C:\Program Files\CMake\bin
).PATH
de
l’utilisateur (vous pouvez aussi indiquer “tous les utilisateurs”) soit
modifié pour inclure le chemin vers ce cmake
.PATH
avec le
chemin vers cmake installé : Le bug ne devrait plus se
manifester.CMakeLists.txt
, vous devez faire régénérer votre projet
==> menu “Projet > Supprimer le cache et reconfigurer” pour que
VisualStudio applique le CMakeLists.txt
avec le nouveau
cmake.