Jc/md/lp-01/06Kernel Tracker1 Debugging Kernel Tracker.
-
Upload
mireille-lamour -
Category
Documents
-
view
118 -
download
0
Transcript of Jc/md/lp-01/06Kernel Tracker1 Debugging Kernel Tracker.
jc/md/lp-01/06 Kernel Tracker 1
Debugging
Kernel Tracker
jc/md/lp-01/06 Kernel Tracker 2
Objectif du chapitre
• Écrire un programme multithread en mode debug
• Explorer Kernel Tracker, outils avancé de mise au point
jc/md/lp-01/06 Kernel Tracker 3
DEBUG Main (1)
#include "stdafx.h"
DWORD WINAPI A_MAIN(LPVOID p);
DWORD WINAPI B_MAIN(LPVOID p);
DWORD WINAPI FIN(LPVOID p);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
jc/md/lp-01/06 Kernel Tracker 4
DEBUG Main (2)
{DWORD dwExitCode;
//Déclaration et création des événements et des threads HANDLE hEvent_A=CreateEvent(NULL,TRUE,FALSE,L"EVENT_A");HANDLE hEvent_B=CreateEvent(NULL,TRUE,FALSE,L"EVENT_B");HANDLE hEvent_fin=CreateEvent(NULL,TRUE,FALSE,NULL);
HANDLE hThread_Fin=CreateThread(0,0,FIN,&hEvent_fin,0,0);HANDLE hThread_A=CreateThread(0,0,A_MAIN,&hThread_Fin,0,0);HANDLE hThread_B=CreateThread(0,0,B_MAIN,&hThread_Fin,0,0);
jc/md/lp-01/06 Kernel Tracker 5
DEBUG Main (3)
//Impression des handles pour identifier les objets dans Kernel Tracker
RETAILMSG(1,(TEXT("MAIN: hThread_A= %x\n"),hThread_A)); RETAILMSG(1,(TEXT("MAIN: hThread_B= %x\n"),hThread_B)); RETAILMSG(1,(TEXT("MAIN: hThread_Fin= %x\n"),hThread_Fin)); RETAILMSG(1,(TEXT("MAIN: hEvent_A= %x\n"),hEvent_A)); RETAILMSG(1,(TEXT("MAIN: hEvent_B= %x\n"),hEvent_B)); RETAILMSG(1,(TEXT("MAIN: hEvent_fin= %x\n"),hEvent_fin));
//Déclenchement de l’événement A SetEvent(hEvent_A);
jc/md/lp-01/06 Kernel Tracker 6
DEBUG Main (4)
//Attente du signal de fin puis de la fin… de A et de B
WaitForSingleObject(hEvent_fin,INFINITE); //Attente…fin
while(GetExitCodeThread(hThread_A,&dwExitCode), dwExitCode == STILL_ACTIVE)
Sleep(0); //…tant que thread A… pas fini
while(GetExitCodeThread(hThread_B,&dwExitCode), dwExitCode == STILL_ACTIVE)
Sleep(0); //…tant que thread B… pas fini
jc/md/lp-01/06 Kernel Tracker 7
DEBUG Main (5)
//Fermeture de tous les handles créés
CloseHandle(hThread_A);
CloseHandle(hThread_B);
CloseHandle(hThread_Fin);
CloseHandle(hEvent_A);
CloseHandle(hEvent_B);
CloseHandle(hEvent_fin);
RETAILMSG(1,(TEXT("MAIN: fin de DEBUG\n")));
return 0;
}
jc/md/lp-01/06 Kernel Tracker 8
DEBUG Thread_A (1)
DWORD WINAPI A_MAIN(LPVOID p)
{
//p est un pointeur sur le handle du thread FIN
DWORD dwExitCode,i,j=0;
//Récupération des handles des événements A et B
HANDLE hEVENT_A=OpenEvent( EVENT_ALL_ACCESS,FALSE,L"EVENT_A");
HANDLE hEVENT_B=OpenEvent( EVENT_ALL_ACCESS,FALSE,L"EVENT_B");
jc/md/lp-01/06 Kernel Tracker 9
DEBUG Thread_A (2)
while(GetExitCodeThread(*(PHANDLE)p,&dwExitCode), dwExitCode == STILL_ACTIVE)
{ WaitForSingleObject(hEVENT_A,INFINITE);//attente… RETAILMSG(1,(TEXT("A_MAIN: j= %d\n"),++j)); for(i=0;i<1000000;i++) //histoire de passer le temps…
; //sans sortir du thread ResetEvent(hEVENT_A); //réinitialisation de…A
SetEvent(hEVENT_B); //Déclenchement de…B }
return 'A';}
jc/md/lp-01/06 Kernel Tracker 10
DEBUG Thread_B (1)
DWORD WINAPI B_MAIN(LPVOID p)
{
//p est un pointeur sur le handle du thread FIN
DWORD dwExitCode,i,j=0;
//Récupération des handles des événements A et B
HANDLE hEVENT_A=OpenEvent( EVENT_ALL_ACCESS,FALSE,L"EVENT_A");
HANDLE hEVENT_B=OpenEvent( EVENT_ALL_ACCESS,FALSE,L"EVENT_B");
jc/md/lp-01/06 Kernel Tracker 11
DEBUG Thread_B (2)
while(GetExitCodeThread(*(PHANDLE)p,&dwExitCode), dwExitCode == STILL_ACTIVE)
{ WaitForSingleObject(hEVENT_B,INFINITE);
RETAILMSG(1,(TEXT("B_MAIN: j= %d\n"),++j)); ResetEvent(hEVENT_B); //réinitialisation de B…
for(i=0;i<1000000;i++) //histoire de passer le temps... ; //sans sortir du thread SetEvent(hEVENT_A); //Déclenchement de A } return 'B';}
jc/md/lp-01/06 Kernel Tracker 12
DEBUG Thread_FIN
DWORD WINAPI FIN(LPVOID p)
{
//p pointeur sur le handle de l’événement fin
MessageBox(NULL,_T("OK pour terminer"), _T("DEBUG"),MB_OK);
return (DWORD)SetEvent(*(PHANDLE)p);
}
jc/md/lp-01/06 Kernel Tracker 13
Exécution de DEBUG
• Générer DEBUG• Télécharger l’image (version Debug)• Exécuter DEBUG pour vérifier son bon
fonctionnement• Fermer l’application• Fermer la fenêtre cible• Nous allons étudier cette application avec l’outil
« Remote Kernel Tracker » proposé avec Platform Builder
jc/md/lp-01/06 Kernel Tracker 14
Options de Build version Debug
jc/md/lp-01/06 Kernel Tracker 15
Variante
• Sous « Kernel Tracker » beaucoup d’événements dus à l’existence des messages seront créés par le système.
• La suppression des messages « RETAIL » dans les threads A ou B, et le remplacement de la boîte de dialogue par une boucle vide dans le thread FIN simplifient les diagrammes observés, mais cela masque les interactions du programme avec le système et avec « Kernel Tracker » lui-même.
jc/md/lp-01/06 Kernel Tracker 16
Outils de Platform Builder
• Platform Builder propose un ensemble d’outils spécialisés et un générateur de macro pour aider à la mise au point d’applications, vérifier le bon fonctionnement temporel, étudier les performances, visualiser les fenêtres, etc.
• Parmi ces outils, le « Remote Kernel Tracker » permet de visualiser graphiquement la chronologie d’une application : création des process, threads, événements, enchaînement des événements, mutex, etc.
jc/md/lp-01/06 Kernel Tracker 17
Découverte de Kernel Tracker
• Téléchargement du noyau• Lancement de Remote Kernel Tracker• Lancement de DEBUG• Collecte des données
– Attente de quelques secondes– Fin de DEBUG après click sur OK– Fin de la collecte après quelques secondes– Déconnexion de la cible
• Analyse des données
jc/md/lp-01/06 Kernel Tracker 18
Démarrage de Remote Kernel Tracker
jc/md/lp-01/06 Kernel Tracker 19
Accepter le choix par défaut : OK
jc/md/lp-01/06 Kernel Tracker 20
Début de Remote Kernel Tracker
jc/md/lp-01/06 Kernel Tracker 21
Après démarrage de DEBUG
jc/md/lp-01/06 Kernel Tracker 22
À la fin de DEBUG
jc/md/lp-01/06 Kernel Tracker 23
Suppression de Auto-Follow Mode
jc/md/lp-01/06 Kernel Tracker 24
Déconnexion de la cible
jc/md/lp-01/06 Kernel Tracker 25
Analyse des données
• Récupération des valeurs des handles dans DEBUG pour identifier les traces
• Étude de diverses phases– Début de DEBUG– Lancement des threads A, B et FIN– Positionnement de l’événement A– Fonctionnement alternatif de A et B– Thread en attente– Fin de DEBUG
• Mesure des temps
jc/md/lp-01/06 Kernel Tracker 26
Récupération des handles
jc/md/lp-01/06 Kernel Tracker 27
Valeur des handles dans DEBUG
• ProcessID : 0x63D9CF8A• ThreadID : 0x63D1013A• hThread_A : 0x03D97A3A• hThread_B : 0x03CECFA2• hThread_Fin : 0x03DB1512• hEvent_A : 0x03D979DA• hEvent_B : 0x03DB1152• hEvent_Fin : 0x03DB140A
jc/md/lp-01/06 Kernel Tracker 28
Phase de démarrage de DEBUG
FIN
A
B
Prologue
jc/md/lp-01/06 Kernel Tracker 29
Positionnement du curseur
Positionnement du curseur par un click gauche
jc/md/lp-01/06 Kernel Tracker 30
Positionnement du marqueur 1
Ouverture du menu par click
droit
jc/md/lp-01/06 Kernel Tracker 31
Positionnement du marqueur 2
Marqueur 1positionné
Curseur déplacé
jc/md/lp-01/06 Kernel Tracker 32
Mesure du temps entre marqueurs
Écart visualisé par une hachure
Écart mesuré numériquement
jc/md/lp-01/06 Kernel Tracker 33
Action directe sur les marqueurs
Dans ce cas le marqueur sera placé à l’endroit du click droit
Ouverture du menu par click droit dans la bande d’affichage des temps
jc/md/lp-01/06 Kernel Tracker 34
Action directe sur les threads
Ouverture du menu par click droit sur le
nom du thread
jc/md/lp-01/06 Kernel Tracker 35
Fonctionnement des threads A et B
B attend
B reprend
Déblocage de A
A reprend
A attend
jc/md/lp-01/06 Kernel Tracker 36
Détail de la mise en attente de B
Déblocage de ASetEvent A
Attente sur BWaitForSingleObject B
jc/md/lp-01/06 Kernel Tracker 37
Détail de la réactivation de A
A reprend avec sa priorité normale (251)
Inversion de priorité
A est à la priorité 130
A revient à sa priorité normale (251)
Le système a posé une section
critique
jc/md/lp-01/06 Kernel Tracker 38
Détail de la mise en attente de A
A dans sa boucle vide
Blocage de AResetEvent A
Déblocage de BSetEvent B
Attente de A WaitForSingleObject A
jc/md/lp-01/06 Kernel Tracker 39
Détail de la réactivation de B
B reprend
ResetEvent B B dans sa boucle vide
jc/md/lp-01/06 Kernel Tracker 40
Attente dans FIN de « OK »
FIN est élu
Le système ferme une section critique
nécessaire pour gérer la boîte de
dialogue
B est élu
Le système ouvre une section critique
nécessaire pour gérer la boîte de
dialogue
jc/md/lp-01/06 Kernel Tracker 41
Réception « OK » et fin du thread B
Message « OK » arrivé
Épilogue de B
Suspension du thread B
MAIN trouve B fini et entre dans le premier Sleep
Fin du thread B
jc/md/lp-01/06 Kernel Tracker 42
Détail de la fin du thread B
B dans la boucle vide
SetEvent A Épilogue
B trouve le thread FIN inactif et sort
jc/md/lp-01/06 Kernel Tracker 43
Fin du thread A
Suspension du thread AÉpilogue de A
Fin du thread A
jc/md/lp-01/06 Kernel Tracker 44
Détail de la fin du thread A
ResetEvent A SetEvent B
A trouve le thread FIN inactif et sort
Épilogue de A
A dans la boucle vide
jc/md/lp-01/06 Kernel Tracker 45
Fermeture des événements
CloseEvent A, CloseEvent BCloseEvent FIN
Suppression de EVENT_FIN
jc/md/lp-01/06 Kernel Tracker 46
Fin du thread FIN
Suspension du thread FIN
Épilogue de DEBUG
Fin de DEBUG
jc/md/lp-01/06 Kernel Tracker 47
Fin du process
Épilogue du process
Suspension de DEBUG
Threads suspendus ou en sommeil
jc/md/lp-01/06 Kernel Tracker 48
Conclusion
• Nous avons exploré différents aspects Kernel Tracker
– Visualisation de l’enchaînement des taches– Mesure des temps– Utilisation en tant qu’analyseur logique