Débugger avec Qt

Formation

En Ligne

Prix sur demande

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Description

  • Typologie

    Formation

  • Méthodologie

    En ligne

Grâce à cette formation vous pourrez acquérir les connaissances nécessaires qui vous permettrons d’ajouter des compétences à votre profil et obtenir de solides aptitude qui vous offriront de nombreuses opportunités professionnelles.

Questions / Réponses

Ajoutez votre question

Nos conseillers et autres utilisateurs pourront vous répondre

À qui souhaitez-vous addresser votre question?

Saisissez vos coordonnées pour recevoir une réponse

Nous ne publierons que votre nom et votre question

Les Avis

Le programme

Introduction du cours

Lorsque l'on programme, il y a une constante qui revient à chaque fois : le débuggage.

Petit rappel pour ce qui ne savent pas ou plus : le débuggage est « l'art » de suivre toutes les opérations d'un programme afin de déterminer l'origine d'une ou plusieurs erreurs.

En effet, lorsque l'on réalise un programme ou une librairie (quel que soit le langage) il y a toujours un moment où on a besoin de débugger. Il s'agit en général d'un travail long et souvent pénible car les erreurs n'apparaissent pas toujours lors de la compilation. Il faut donc faire en sorte de les traquer une à une.

Ce tutoriel vous propose donc d'apprendre une des nombreuses manières de débugger vos programmes ou vos librairies, et ce grâce à Qt.

Pour comprendre ce tutoriel il faut connaitre un minimum le C++ (notamment la POO et la notion d'objet). Et comme les techniques de débuggage portent sur Qt, il est mieux de savoir de quoi on parle.

Comment débugger ?

Il existe de nombreuses manières de débugger, certaines fonctionnant mieux que d'autres. Mais, en général, toutes fonctionnent relativement bien et ont chacune leurs avantages / désavantages.
Le choix d'une technique de débuggage ressemble au choix d'un OS (Operating System : système d'exploitation) : chacun dit que le sien est meilleur que les autres et tente d'en convaincre tout le monde (j'exagère un peu, je sais ;) ). Personnellement je pense que la meilleure technique de débuggage est celle avec laquelle vous vous sentez le plus à l'aise.

Parmi les nombreuses manières de débugger un programme, voici les deux principales :

  • Utiliser un debugger : cette technique consiste à utiliser un programme qui intègre des fonctions de débuggage comme les « breakpoints » ou la visualisation des variables en temps réel ;

    • Avantage : facilité de mise en œuvre, utilisation simple et rapide ;

    • Désavantage : — (ce n'est pas vrai, mais voir ci-dessous) ;

  • Utiliser la console : ici, on modifie le code pour ajouter des lignes qui donnent des informations sur le déroulement du programme ;

    • Avantage : — (idem, voir plus bas) ;

    • Désavantage : obligation de re-compiler à chaque modification du débuggage.

Heu… Je ne vois pas trop où est la difficulté de choisir telle ou telle technique. Tu es sûr de ce que tu dis ?

Absolument certain, mais le débuggage ne s'utilise pas que pour débugger des programmes. On peut aussi débugger des librairies/plugins et autres objets non exécutables. Dans ces cas-là, il est impossible d'utiliser la visualisation des variables et les "breakpoints" directement sur les fichiers de sortie. En effet, ceux-ci ne disposent pas de fonction main, donc le débugger ne sait pas par où il doit commencer. Donc les debuggers perdent tout leur intérêt dans ce genre de cas. La seule manière d'utiliser un debugger avec une librairie/plugin, c'est de créer un code exemple puis de lancer le debugger avec l'exemple.
On peut donc deviner qu'il devient plus facile d'utiliser la deuxième méthode.

Comme je l'ai dit plus haut, ce tutoriel est là pour vous apprendre à vous servir des outils mis en place par Qt pour le débuggage. Comme Qt est une librairie, elle ne propose pas de debugger en tant que programme, mais elle offre de nombreux outils pour afficher des « choses » dans la console. C'est donc sur cet aspect qu'on va se pencher.

Ne perdez pas de vue que c'est aussi utilisable pour des programmes, notamment sur les systèmes embarqués (quoique la plupart d'entre eux ont des debuggers spécifiques fournis). Donc n'hésitez pas à lire la suite.

De plus, les fonctions de débuggage proposées par Qt peuvent transmettre des informations au debugger (principalement sous Windows). Donc la suite n'est pas forcément à négliger.

Mode release/debug

La première chose à savoir lorsqu'on souhaite faire du débuggage avec Qt, c'est qu'il existe, en gros, deux modes de compilation :

  • Le mode debug : lors de l'exécution et notamment lors d'une erreur, les fonctions renvoient plus d'informations concernant ce qui c'est produit. En contrepartie les librairies sont plus lourdes (environ facteur 6 pour QtCore) ;

  • Le mode release : l'inverse du mode debug. Les librairies sont plus légères mais donnent moins d'informations.

D'une manière générale, lorsque vous téléchargez une librairie, vous obtenez la version release (s'il y avait un mode debug). En effet, une librairie en mode debug ne donne des informations que sur elle-même en cas de problème interne, donc ça importe peu pour la plupart des utilisateurs. Cependant, il reste toujours possible de récupérer la version debug d'une librairie.
Comme la librairie Qt se veut « libre », et qu'on peut la recompiler à volonté, les créateurs ont aussi donné accès aux versions debug, celles-ci étant incluses dans les « packages ».

Pour savoir si vous utilisez une librairie en mode release ou non sous Qt, regardez le nom de la dll/so : si elle finit par un « d », sans tenir compte du chiffre (exemple « QtCored4.dll »), c'est qu'elle est en mode debug.

Changer le mode

Comme vous pouvez le constater, il peut être fort utile de pouvoir compiler à volonté soit en mode debug, soit en mode release. D'ailleurs, le changement se fait non seulement pour les librairies de Qt dont vous avez besoin, mais cela permet deux-trois choses dans votre propre programme ou votre propre librairie que nous verrons légèrement plus tard.

Pour changer de mode, c'est très simple. Si vous avez suivi le tutoriel de M@teo21 sur Qt, tâchez de vous rappeler comment on compile un projet. En fait, ça se résumait à trois « instructions » dans la console (dans le cas d'un nouveau projet). Les voici :

qmake -project qmake make

Si on prend les instructions une à une, voici ce qu'elles font :

  • qmake -project : Qt génère automatiquement votre fichier de projet (.pro) en fonction des fichiers présents ;

  • qmake : Qt lit votre fichier projet (.pro) et génère les makefiles ;

  • make : Qt utilise MinGW (le compilateur) et les makefiles pour créer le fichier de sortie (en général un exécutable).

La modification que nous devons apporter se situe entre la première et la deuxième étape. En effet, le mode de compilation se décide dans le fichier de projet.
Si vous l'ouvrez (avec le bloc-notes par exemple), vous devriez obtenir quelque chose comme ceci :

###################################################################### # Automatically generated by qmake (2.01a) lun. 23. mars 22:46:38 2009 ###################################################################### TEMPLATE = app TARGET =  DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += main.cpp

Pour ceux que ça intéresserait, la documentation de Qt sur le qmake est très bien fournie. Et le réglage d'un projet Qt permet de faire de grandes choses.

Pour le réglage du mode de compilation, tout se passe avec la variable CONFIG. Comme celle-ci est déjà pré-remplie (même si on ne la voit pas), il faudra employer le symbole += pour indiquer qu'on souhaite ajouter des propriétés.

Si vous souhaitez faire de la compilation en mode debug, vous avez deux choix :

  • ne rien faire. Par défaut Qt est réglé sur le mode debug. Mais il est possible que ça change en fonction des versions (les versions antérieures de Qt étaient en mode release par défaut) ;

  • ajouter « debug » après le += de la variable CONFIG.

Et si vous préférez le mode release, il suffit de mettre « release » à la place de « debug ».

Facile, non ?

Si vous vous amusez à placer les deux en même temps, c'est celui placé en dernier qui est pris en compte.

Quel que soit le mode de compilation choisi, vous pouvez à tout moment ajouter aussi « console ». Cela force — dans le cas d'une application graphique — à ouvrir une console en arrière-plan. C'est très pratique pour voir vos propres messages de débuggage (on va voir dans un instant comment faire) mais aussi pour voir ceux de Qt, notamment concernant les signaux ou les slots qui ne se sont pas connectés ensemble (quelle qu'en soit la raison).

Le mode « console » n'a d'effet que sous Windows. Pour les autres, tout dépend de la manière dont vous lancez le programme.

Imaginons qu'on se place en mode debug. Voici ce qu'on obtient :

###################################################################### # Automatically generated by qmake (2.01a) lun. 23. mars 22:46:38 2009 ###################################################################### TEMPLATE = app CONFIG +=  console debug TARGET =  DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += main.cpp

Vous pouvez voir que j'ai aussi ajouté le mot « console ».

Mode debug et release en même temps

En fait, il est possible de considérer qu'il existe un troisième mode de compilation… Celui-ci est une combinaison des deux autres car il effectue les deux compilations en même temps (enfin l'une après l'autre, sans pause).
Pour cela, remplacez le « debug » ou le « release » par « debug_and_release ».

La documentation de Qt dit qu'il est possible que l'utilisation de ce mode puisse causer des effets inattendus. Je vous conseille donc de faire très attention quand vous vous lancez dans ce genre de choses.

Dans ce cas, pour compiler, il vous faudra faire make all à la place de make.
Cependant, il reste possible d'utiliser make pour compiler les deux modes. Pour faire ça, ajoutez en plus de « debug_and_release » un « build_all ». Voilà, maintenant vous pouvez compiler les deux modes à la suite avec un simple make.

Prêt(e) à entrer dans le débuggage profond ?

Afficher des messages de débuggage

Enfin, on attaque la partie vraiment pratique.

Avant que tu ne commences… Pourquoi présenter des fonctions faites par Qt alors qu'un simple « cout » suffirait (maintenant qu'on sait afficher la console) ?

Très bonne question. En fait absolument rien ne vous empêche d'employer le bon vieux (mais fidèle) « cout ».
Mais voici deux-trois raisons de ne PAS l'utiliser :

  • Une question « d'homogénéité » : dans tout votre programme on utilise Qt, alors pourquoi juste pour le débuggage utiliserait-on la bibliothèque standard ?

  • Un grand nombre de classes Qt intègrent déjà un opérateur de flux vers la console pour se décrire elles-mêmes. C'est mieux que de devoir toutes les réécrire pour cout.

Après c'est à vous de voir ce que vous préférez.

Les fonctions de base

Qt intègre quatre fonctions dédiées au débuggage et aux rapports d'erreurs. Chacune a un but défini. Les voici :

  • qCritical : le simple rapport d'erreur, qui ne fait pas obligatoirement quitter le programme (voir qFatal) ;

  • qDebug : taillée exprès pour le débuggage ;

  • qFatal : identique à qCritical, mais implique en générale que le programme se termine juste après (une erreur fatale donc :p ) ;

  • qWarning : pour les messages de prévention.

Je vous invite vivement à consulter la doc les concernant, c'est très utile.
Par défaut, les messages sont envoyés sur « stderr » (le flux standard des erreurs). Dans le cas d'une application graphique sans console, c'est envoyé vers le débugger (s'il est présent, sinon adieu le message :-° )

ATTENTION : Ces fonctions sont très très basiques et fonctionnent comme les (très vieilles) fonctions du C, c'est-à-dire du genre de la fonction « printf » (ouh, que c'est vieux). C'est-à-dire une chaîne de caractère avec des « %s » pour les chaînes de caractères, « %d » pour les entiers, etc.
De plus elles vont automatiquement à la ligne. Donc pas besoin de finir avec des « \n ».

QUOI ? Mais mais… et la classe QString ?

Je pense que les programmeurs de Qt (merci à Nanoc), lorsqu'ils ont créé ces fonctions, ont réfléchi à la chose suivante : si on emploie des fonctions comme qCritical ou qFatal, c'est qu'a priori quelque chose ne va pas. Si on utilise la classe QString alors que quelque chose ne va pas, QString risque aussi d'avoir un problème. Et là on va avoir de gros problèmes car une erreur se produit pendant le rapport d'une autre erreur. Et cette erreur va elle aussi être rapportée en appelant QString, qui provoquera une nouvelle erreur qui…

Assez peu pratique, non ? Et puis dans le cas où il se produit une erreur dans QString, on ne peut pas appeler les fonction prévues car celle-ci fonctionne avec QString.

Cependant, dans le cadre de vos projets, vous partez de l'hypothèse que Qt fonctionne correctement. De toute manière, s'il y a un problème interne, c'est Qt qui gère. Donc rien ne vous empêche d'utiliser QString avec ces fonctions. Et comme nous parlons de Qt, ils ont quand même prévu les choses, et mettent donc à notre disposition deux mécanismes pour nous simplifier la vie.

Simplifiez-vous la vieqPrintable

Certains connaissent déjà cette fonction miracle : qPrintable. On en peut pas faire plus simple : vous lui donnez en paramètre une QString et elle vous sort... un « char * ». Parfait pour le donner à votre fonction.

Voyons un exemple :

qFatal(qPrintable(tr("Erreur fatale : la variable %1 n'existe pas").arg(i)));

Comme vous pouvez le voir, ça permet aussi d'utiliser directement la fonction « tr » (pour d'éventuelles traductions !).

Personnellement, je vous conseille de créer une petite macro, du genre :

#define FATAL_ERROR(msg) qFatal(qPrintable(msg))

Comme ça, plus de problème.

Passons donc au deuxième mécanisme (le meilleur).

QtDebug

Comme je vous l'ai dit légèrement plus haut, un des avantages de Qt c'est que nombre de ses classes savent se représenter seules dans une console. Pourtant aucune ne semble avoir de fonction du style char * debug ()...

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Débugger avec Qt

Prix sur demande