Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Cet article fournit des informations utiles pour le débogage de threads, notamment sur la définition des noms de threads pour le code natif et managé.
Conseils C/C++
Voici quelques conseils que vous pouvez utiliser lors du débogage de threads dans du code natif :
Vous pouvez afficher le contenu du bloc d’informations de thread en tapant
@TIBdans la fenêtre Observateur ou dans la boîte de dialogue Examen rapide.Vous pouvez afficher le dernier code d’erreur du thread actuel en entrant
@Errdans la fenêtre Observateur ou la fenêtre de dialogue Observateur immédiat.Les fonctions C Run-Time Libraries (CRT) peuvent être utiles pour déboguer une application multithread. Pour plus d’informations, consultez _malloc_dbg.
Définir un nom de thread en C/C++
Le nommage de thread est possible dans n’importe quelle édition de Visual Studio. Le nommage des threads est utile pour identifier les threads intéressants dans la fenêtre Threads lors du débogage d’un processus en cours d’exécution. Avoir des threads nommés de façon reconnaissable peut également être utile lors de l'exécution d'un débogage post-mortem via l'inspection d'un dump de crash et lors de l'analyse des captures de performance à l'aide de différents outils.
Méthodes de définition d’un nom de thread
Il existe deux façons de définir un nom de thread. La première consiste à utiliser la fonction SetThreadDescription . La seconde consiste à lever une exception particulière pendant que le débogueur Visual Studio est attaché au processus. Chaque approche présente des avantages et des mises en garde. L'utilisation de SetThreadDescription est prise en charge à partir de Windows 10 version 1607 ou Windows Server 2016.
Il est important de noter que les deux approches peuvent être utilisées ensemble, si vous le souhaitez, puisque les mécanismes par lesquels ils travaillent sont indépendants les uns des autres.
Définir un nom de thread à l’aide de SetThreadDescription
Avantages :
- Les noms de threads sont visibles lors du débogage dans Visual Studio, que le débogueur soit ou non attaché au processus au moment où SetThreadDescription est appelé.
- Les noms de fils sont visibles lors du débogage post-mortem par le chargement d'un vidage de mémoire dans Visual Studio.
- Les noms de threads sont également visibles lors de l’utilisation d’autres outils, tels que le débogueur WinDbg et l’analyseur de performances Windows Performance Analyzer .
Avertissements :
- Les noms de threads sont visibles uniquement dans Visual Studio 2017 version 15.6 et versions ultérieures.
- Lors du débogage post-mortem d’un fichier de vidage sur incident, les noms de threads sont visibles uniquement si l'incident a été créé sur Windows 10 version 1607, Windows Server 2016 ou versions ultérieures de Windows.
Exemple :
#include <windows.h>
#include <processthreadsapi.h>
int main()
{
HRESULT r;
r = SetThreadDescription(
GetCurrentThread(),
L"ThisIsMyThreadName!"
);
return 0;
}
Définissez un nom de thread en cas de lancement d'une exception.
Une autre façon de définir un nom de thread dans votre programme consiste à transmettre le nom de thread souhaité au débogueur de Visual Studio en déclenchant une exception spécialement configurée.
Avantages :
- Fonctionne dans toutes les versions de Visual Studio.
Avertissements :
- Fonctionne uniquement si le débogueur est attaché au moment où la méthode basée sur l’exception est utilisée.
- Les noms de threads définis à l'aide de cette méthode ne seront pas disponibles dans les dumps ou les outils d'analyse des performances.
Exemple :
La SetThreadName fonction illustrée ci-dessous illustre cette approche basée sur des exceptions. Notez que le nom du thread est automatiquement copié dans le thread afin que la mémoire du threadName paramètre puisse être libérée une fois l’appel SetThreadName terminé.
//
// Usage: SetThreadName ((DWORD)-1, "MainThread");
//
#include <windows.h>
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
void SetThreadName(DWORD dwThreadID, const char* threadName) {
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
#pragma warning(push)
#pragma warning(disable: 6320 6322)
__try{
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER){
}
#pragma warning(pop)
}
Définir un nom de thread dans le code managé
Le nommage de thread est possible dans n’importe quelle édition de Visual Studio. Le nommage des threads est utile pour assurer le suivi des threads dans la fenêtre Threads .
Pour définir un nom de thread dans le code managé, utilisez la Name propriété.
Example
public class Needle
{
// This method will be called when the thread is started.
public void Baz()
{
Console.WriteLine("Needle Baz is running on another thread");
}
}
public void Main()
{
Console.WriteLine("Thread Simple Sample");
Needle oNeedle = new Needle();
// Create a Thread object.
System.Threading.Thread oThread = new System.Threading.Thread(oNeedle.Baz);
// Set the Thread name to "MyThread".
oThread.Name = "MyThread";
// Starting the thread invokes the ThreadStart delegate
oThread.Start();
}