950 likes | 1.08k Views
Debugging. Élémentaire. Objectif du chapitre. Premier contact avec les outils de mise au point Génération en vue de debug Usage des points d’arrêt, pas à pas Visualisations diverses Code Variables Mémoire Pile …. Objectifs (1).
E N D
Debugging Élémentaire Debug
Objectif du chapitre • Premier contact avec les outils de mise au point • Génération en vue de debug • Usage des points d’arrêt, pas à pas • Visualisations diverses • Code • Variables • Mémoire • Pile • … Debug
Objectifs (1) • La mise au point de programmes (debugging) nécessite l’emploi de techniques particulières • Platform Builder offre • Un ensemble d’outils usuels • Exécution du programme en pas à pas • Pose ou suppression de points d’arrêt • Visualisation des variables, de la mémoire, des registres • Suivi des enchaînements de fonctions, etc. • Un outil « Kernel Tracker » pour visualiser la chronologie des exécutions Debug
Objectifs (2) • Pour utiliser les possibilités de mise au point, la cible doit être construite dans le mode particulier « Debug » par opposition au mode « Release » qui correspond à une version d’exploitation • Étude du debugger en deux phases • Visualisations diverses, Breakpoint, etc. • Kernel Tracker ultérieurement Debug
Point de départ • Générer une plate-forme en mode Debug • Créer et générer une application avec un main et des fonctions très simples • Exploration (partielle) de l’outil de debug • Messages • Visualisation du code source • Breakpoint • Visualisation des variables, de la mémoire • Visualisation du code assembleur • Visualisation de la pile Debug
Génération de la plate-forme « Debug » • Utiliser l’assistant, comme précédemment, avec éventuellement un nouveau nom • Au pas 6 de l’assistant, modifier les options • Cocher dans les options de la liste « Debug » : « Enable Image Larger than 32 MB » • Sortir de l’assistant par « Finish » • Sélectionner la configuration active « Debug » • Générer la plate-forme (Build Platform) Debug
Modification des options Debug
Génération de l’image Debug
Exécution d’une application • Sans inclusion dans l’image Création du .exe Téléchargement du noyau Éxécution par la commande « Run Program » • Avec inclusion dans l’image Création du .exe Refaire une image avec choix de l’option d’insertion Téléchargement du noyau avec l’application Exécution à partir de la cible par la méthode Windows Debug
Options de génération • Pour voir les options de génération avec ou sans inclusion, nous prenons une application de type WCE Application • Noms de nos applications écrits en majuscules pour les distinguer facilement des applications proposées par Windows CE • Nom de l’application : BRKP • Nous ajouterons le code par la suite Debug
Application BRKP • Faire la somme et le produit de deux nombres entiers positifs avec • Une fonction somme • Une fonction produit • Des variables statiques • Des variables dynamiques • Des passages d’arguments • Introduire des messages de contrôle Debug
Messages d’aide à la mise au point • Édition habituelle de messages de contrôle dans l’application par des printf ou équivalents • En plus, édition de messages par des macros dans la fenêtre de sortie de l’émulateur, et non dans le contexte de la cible • RETAILMSG en version Retail • RETAILMSG et DEBUGMSG en version Debug Debug
Macro RETAILMSG • RETAILMSG(cond, printf_exp) • Impression si la condition est vraie de ce qu’on mettrait dans un printf • Impression faite par une fonction équivalente à printf mais qui écrit dans la fenêtre de sortie de l’émulateur et non dans la cible émulée Exemple : RETAILMSG(1,(TEXT("Main: adresse de i= %x\n"),&i)); Équivalent dans la fenêtre de sortie à : printf("Main: adresse de i= %x\n",&i); Debug
Application BRKP (1) #include "stdafx.h" //prototypes des fonctions DWORD dwSomme(DWORD dwA,DWORD dwB); DWORD dwProduit(DWORD dwA,DWORD dwB); DWORD dwValeur; //juste pour avoir une variable statique int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) Debug
Application BRKP (2) { DWORD i,j; //Visualisation des adresses dans la fenêtre de sortie RETAILMSG(1,(TEXT("Main: adresse de i= %x\n"),&i)); RETAILMSG(1,(TEXT("Main: adresse de j= %x\n"),&j)); RETAILMSG(1,(TEXT("Main: adresse de valeur= %x\n"),&dwValeur)); //Calcul de somme et produit des entiers positifs 5 et 3 i=5; j=3; Debug
Application BRKP (3) RETAILMSG(1,(TEXT("Main: i=%u j=%u\n"),i,j)); dwValeur=dwSomme(i,j); RETAILMSG(1,(TEXT("Main: i+j=%u\n"),dwValeur)); printf(("Main: i=%u j=%u dwValeur =%u \n"),i,j,dwValeur); dwValeur=dwProduit(i,j); RETAILMSG(1,(TEXT("Main: i*j=%u\n"),dwValeur)); printf(("Main: i=%u j=%u dwValeur =%u \n"),i,j,dwValeur); getchar(); return 0; } Debug
Application BRKP (4) DWORD dwSomme(DWORD dwA,DWORD dwB) { //Addition de A et B par une méthode archaïque DWORD dwC=0; while(dwA--) dwC++; while(dwB--) dwC++; return dwC; } Debug
Application BRKP (5) DWORD dwProduit(DWORD dwA,DWORD dwB) { // Multiplication de A et B par une méthode simpliste DWORD dwC; for(dwC=0;dwB;dwB--) dwC=dwSomme(dwA,dwC); return dwC; } Debug
Insertion et suppression de breakpoints • Les breakpoints peuvent être placés ou enlevés avant ou après le lancement de l’application • Avant lancement du noyau • Positionner le curseur souris sur une ligne du programme • Faire un click droit pour ouvrir le menu • Faire Insert/Remove Breakpoint • Après lancement du noyau, il faut que le debugger soit arrêté Debug
Fenêtres en debug • Dans la fenêtre principale de Platform Builder la fenêtre Workspace est différente et donne accès à des commandes après chargement de la cible • D’autres fenêtres sont spéciales pour le debug et accessibles par le menu View, sous-menu Debug Windows, ou par une barre de contrôle • Fenêtres libres ou ancrées en fenêtre principale • Mémorisation des caractéristiques des fenêtres • Fermeture par l’icône Windows Debug
Écran avec la fenêtre des variables Fenêtre nouvelle disponible pour des commandes lignes (shell) Variables Fenêtre principale Debug
Exemple de fenêtres ancrées Registres du CPU Fenêtre nouvelle disponible pour des commandes lignes (shell) Fenêtre principale Watch Contexte Fenêtre de sortie Debug
Barre de commande « Debug » • Ouverte comme toutes les barres de commandes par un click droit dans une barre existante et coche de la case • Une série d’icônes correspond à des commutateurs pour l’ouverture ou la fermeture des fenêtres de debug • Une autre série correspond à l’exécution du code : Go simple (jusqu’à un point d’arrêt), pas à pas, avec saut d’une fonction, etc. • Les bulles d’aide sont explicites Debug
Essai de BRKP • Génération de la plate-forme • Génération de l’application • Génération de l’image • Téléchargement du noyau avec ou sans l’application suivant les choix • Exécution du programme • Fermeture de la cible • Déconnexion Debug
Cible vierge Debug
Exécution par la commande shell Commande du shell s BRKP s pour start Debug
Fenêtres du debugger après exécution Messages Messages Debug
Cible après exécution Attente du caractère Entrée Taper Entrée pour finir BRKP Debug
Pose d’un breakpoint • Pose avant ou pendant la session de debug • Placer le curseur sur une ligne de code • Ouvrir le menu contextuel par un click droit • Insérer un point d’arrêt, marqué par un rond rouge en marge (en fait c’est un commutateur qui insère ou supprime un point d’arrêt) • Relancer le programme s’il ne l’est pas • Au début, on doit observer une flèche jaune superposée au premier point d’arrêt Debug
Arrêt du debugger Icône d’arrêt Debug
Arrêt sur point d’arrêt Debug
Exécution du programme en debug • Chaque commande Go (menu ou icône) provoque l’exécution du programme jusqu’à : • Rencontre d’un point d’arrêt • Rencontre d’une erreur d’exécution • Fin normale du programme • La commande « Run Program » charge le programme dont on donne le nom puis déclenche une commande Go • Exécution contrôlée en pas à pas par diverses commandes d’avance Debug
Avance d’un pas • Avance par • Le menu « Debug » • Les touches de fonction du clavier • Les icônes (dessins et bulles explicites) • Plusieurs types d’avance • Un pas dans la fonction (Step Into) • Un pas en sautant la fonction (Step Over) • Un pas en ressortant de la fonction (Step Out) • Jusqu’au curseur (Run to Cursor) Debug
Avance d’un pas simple Avance un pas Debug
Après avance d’un pas simple Fenêtre des variables i à jour, j ? Messages Debug
Avance d’un pas avec saut Avance avec saut Avance avec saut de la fonction pour ne pas exécuter toute la fonction en pas à pas j à jour Debug
Avance avec sortie de la fonction • Ce type de pas (Step Out) permet de cesser l’examen d’une fonction en pas à pas en retournant directement chez l’appelant • Utile quand on est entré par inadvertance dans une fonction déjà au point qu’on ne désire pas dérouler en pas à pas • Utile en particulier quand on est entré dans une fonction fournie par Platform Builder pour laquelle on ne dispose pas du code source Debug