Déboguer les applications multithread dans Visual Studio
Un thread est une séquence d'instructions à laquelle le système d'exploitation alloue du temps processeur. Chaque processus exécuté dans le système d'exploitation se compose d'au moins un thread. Les processus qui comportent plusieurs threads sont appelés multithread.
Les ordinateurs avec plusieurs processeurs, des processeurs multicœur ou des processus d'hyperthreading peuvent exécuter peuvent exécuter plusieurs threads en même temps. Le traitement parallèle à l’aide de nombreux threads peut considérablement améliorer les performances du programme, mais cela peut également rendre le débogage plus difficile, car vous effectuez le suivi de nombreux threads.
Le traitement en parallèle parfait n'est pas toujours possible. Les threads doivent parfois être synchronisés. Un thread peut attendre le résultat d'un autre thread ou un thread peut avoir besoin d'un accès exclusif à une ressource utilisée par un autre thread. Les problèmes de synchronisation sont une cause courante de bogues dans les applications multithread. Les threads attendent parfois une ressource qui n'est jamais disponible. Cet état est appelé interblocage.
Threads et processus
Les threads et les processus sont des concepts liés en informatique. Tous deux représentent des séquences d'instructions qui doivent s'exécuter dans un ordre spécifique. Les instructions dans des threads ou processus séparés, toutefois, peuvent s'exécuter en parallèle.
Les processus existent dans le système d'exploitation et correspondent à ce que les utilisateurs voient sous la forme de programmes ou d'applications. Un thread, en revanche, existe dans un processus. C’est pour cette raison que les threads sont parfois appelés processus légers. Chaque processus est constitué d'un ou de plusieurs threads.
L’existence de plusieurs processus permet à un ordinateur d’effectuer plusieurs tâches à la fois. L'existence de plusieurs threads permet à un processus de séparer le travail à exécuter en parallèle. Sur un ordinateur multiprocesseur, les processus ou les threads peuvent s'exécuter sur différents processeurs. Ce type d'exécution permet un véritable traitement en parallèle.
Outils pour le débogage d’applications multithread
Visual Studio fournit différents outils à utiliser pour déboguer des applications multithreads.
Pour les threads, les outils principaux pour le débogage des threads sont la fenêtre Threads, les marqueurs de thread dans les fenêtres sources, la fenêtre Stacks parallèles, la fenêtre Espion parallèle et la barre d’outils Emplacement du débogage. Pour en savoir plus sur la Threads fenêtre et emplacement de débogage barre d’outils, consultez procédure pas à pas : Déboguer à l’aide de la fenêtre Threads. Pour savoir comment utiliser les fenêtres Stacks parallèles et Espion parallèle, consultez Prise en main du débogage d’une application multithread. Les deux rubriques montrent comment utiliser des marqueurs de thread.
Pour le code qui utilise la bibliothèque parallèle de tâches (TPL) ou le runtime d’accès concurrentiel, les outils principaux pour le débogage sont la fenêtre Stacks parallèles, la fenêtre Espion parallèle et la fenêtre Tâches, qui prend également en charge JavaScript. Pour commencer, consultez Guide pas à pas : débogage d’une application parallèle et Guide pas à pas : débogage d’une application AMP C++.
Pour le débogage de threads sur le GPU, l’outil principal est la fenêtre Threads GPU. Voir Guide pratique pour utiliser la fenêtre Threads GPU.
Les principaux outils pour le débogage des processus sont la boîte de dialogue Attacher au processus, la fenêtre Processus et la barre d'outils Emplacement de débogage.
Visual Studio fournit également des points d'arrêt et des points de trace puissants, qui peuvent s'avérer utiles lors du débogage d'applications multithread. Utilisez des conditions de point d’arrêt et des filtres pour placer des points d’arrêt sur des threads individuels. Les points de trace vous permettent de suivre l’exécution de votre programme sans rupture, afin d’étudier les problèmes tels que les interblocages. Pour plus d’informations, consultez Actions de point d’arrêt et points de trace.
Le débogage d'une application multithread comportant une interface utilisateur peut s'avérer tout particulièrement difficile. Vous pouvez envisager d'exécuter l'application sur un deuxième ordinateur et d'utiliser le débogage distant. Pour plus d’informations, consultez Débogage à distance.
Le tableau suivant affiche les informations disponibles et les actions que vous pouvez exécuter depuis chacun de ces emplacements :
Interface utilisateur | Informations disponibles | Actions que vous pouvez effectuer |
---|---|---|
Boîte de dialogue Attacher au processus | Processus disponibles auxquels vous pouvez attacher : - Nom de processus (.exe) - Numéro d’identifiant de processus - Titre de barre de menus - Type (Managé v4.0 ; Managé v2.0, v1.1, v1.0 ; x86 ; x64 ; IA64) - Nom d’utilisateur (nom du compte) - Numéro de session |
Sélectionnez un processus auquel attacher Sélectionnez un ordinateur distant Modifiez le type de transport pour la connexion aux ordinateurs distants |
Fenêtre Processus | Processus attachés : - Nom du processus - Numéro d’identifiant de processus - Chemin pour traiter .exe - Titre de barre de menus - État (Arrêt. En cours d’exécution) - Débogage (natif, managé, etc.) - Type de transport (par défaut, natif sans authentification) - Qualificateur de transport (ordinateur distant) |
Outils : - Attacher - Détacher - Terminer Menu contextuel : - Attacher - Détacher - Détacher lorsque le débogage est arrêté - Terminer |
Fenêtre Threads | Threads dans le processus actuel : - Identifiant du thread - Identifiant managé - Catégorie (thread principal, thread d’interface, gestionnaire d’appel de procédure distante ou thread de travail) - Nom du thread - Emplacement de création du thread - Priorité - Masque d’affinité - Compteur suspendu - Nom du processus - Indicateur - Indicateur suspendu |
Outils : - Rechercher - Rechercher la pile des appels - Signaler uniquement mon code - Signaler la sélection de modules personnalisés - Grouper par - Colonnes - Développer/réduire la pile des appels - Développer/Réduire les groupes - Figer/libérer les threads Menu contextuel : - Afficher les threads dans la source - Basculer vers un thread - Figer un thread en cours d’exécution - Libérer un thread figé - Marquer un thread pour un examen plus détaillé - Supprimer l’indicateur d’un thread - Renommer un thread - Afficher et masquer des threads Autres actions : - Afficher la pile d’appel d’un thread dans un DataTip |
Fenêtre source | Les indicateurs de thread de la marge gauche signalent un ou plusieurs threads (option désactivée par défaut, activée à l’aide du menu contextuel de la fenêtre Threads) | Menu contextuel : - Basculer vers un thread - Marquer un thread pour un examen plus détaillé - Supprimer l’indicateur d’un thread |
Barre d’outils Emplacement de débogage | - Processus actuel - Interrompre l’application - Redémarrer l’application - Interrompre et quitter l’application - Thread actuel - Activer/désactiver l’état de l’indicateur de thread actuel - Afficher uniquement les threads avec indicateur - Afficher uniquement le processus actuel - Cadre de pile actuel |
- Basculer vers un autre processus - Interrompre, reprendre ou quitter l’application - Basculer vers un autre thread dans le processus actuel - Basculer vers un autre cadre de pile dans le thread actuel - Ajouter ou supprimer l’indicateur de threads actuels - Afficher uniquement les threads avec indicateur - Afficher uniquement le processus actuel |
Fenêtre Piles parallèles | - Piles des appels pour plusieurs threads dans une fenêtre. - Cadre de pile actif pour chaque thread. - Appelants et appelés pour une méthode. - Détection des interblocages |
- Éliminer les threads spécifiés par filtrage - Filtrer les piles de code externe - Basculer vers la vue Tâches - Ajouter ou supprimer l’indicateur d’un thread - Zoom - Copier des frames de pile - Enregistrer/exporter toutes les piles en tant qu’image |
Fenêtre Espion parallèle | - La colonne d'indicateur, où vous pouvez marquer un thread auquel vous souhaitez apporter une attention spéciale. - La colonne de cadre, dans laquelle une flèche indique le cadre sélectionné. - Une colonne configurable qui peut afficher l’ordinateur, le processus, la mosaïque, la tâche et le thread. |
- Ajouter ou supprimer l’indicateur d’un thread - Afficher uniquement les threads avec indicateur - Basculer les cadres - Trier une colonne - Regrouper des threads - Figer ou libérer les threads - Exporter les données dans la fenêtre Espion parallèle |
Fenêtre Tâches | - Affichez des informations sur les objets Task, notamment l’identifiant de la tâche, son état (planifié, en cours, en attente, bloqué), ainsi que le thread qui lui est assigné. - Emplacement actuel dans la pile des appels. - Délégué passé à la tâche au moment de la création |
- Basculer vers la tâche actuelle - Ajouter ou supprimer l’indicateur d’une tâche - Figer ou libérer une tâche |
Fenêtre Threads GPU | - La colonne d'indicateur, où vous pouvez marquer un thread auquel vous souhaitez apporter une attention spéciale. - La colonne de thread actuelle, dans laquelle une flèche jaune indique le thread actuel. - La colonne Nombre de threads, qui affiche le nombre de threads au même emplacement. - La colonne Ligne, qui affiche la ligne de code où chaque groupe de threads est situé. - La colonne Adresse, qui affiche l’adresse de l’instruction où chaque groupe de threads est localisé. - La colonne Emplacement, qui correspond à l’emplacement dans le code de l’adresse. - La colonne État, qui indique si le thread est actif ou bloqué. - La colonne Mosaïque, qui indique l’index de mosaïque des threads dans la ligne. |
- Passer à un autre thread - Afficher une mosaïque et un thread en particulier - Afficher ou masquer une colonne - Trier par colonne - Regrouper des threads - Figer ou libérer les threads - Ajouter ou supprimer l’indicateur d’un thread - Afficher uniquement les threads avec indicateur |