Préparation au débogage de l’application de service
Cette rubrique répertorie toutes les étapes préparatoires qui peuvent être requises avant le débogage d’une application de service. Les étapes requises dans votre scénario dépendent de l’option d’attachement que vous avez choisie et de la configuration de débogage que vous avez choisie. Pour obtenir la liste de ces choix, consultez Choisir la meilleure méthode pour déboguer une application de service.
Chacune des étapes préparatoires décrites dans cette rubrique spécifie les conditions dans lesquelles elle est requise. Ces étapes peuvent être effectuées dans n’importe quel ordre.
Activer le débogage du code d’initialisation
Si vous envisagez de déboguer l’application de service à partir du début de son exécution, y compris son code d’initialisation, cette étape préparatoire est requise.
Recherchez ou créez la clé de Registre suivante, où ProgramName est le nom du fichier exécutable de l’application de service :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProgramName
ProgramName doit inclure l’extension de nom de fichier, mais pas le chemin d’accès. Par exemple, ProgramName peut être Myservice.exe ou Thisservice.dll.
Sous cette clé de registre, créez une donnée de type chaîne intitulée Debugger. La valeur de cette chaîne doit indiquer le chemin d'accès complet ainsi que le nom du fichier du débogueur à associer à l'application de service.
Si vous envisagez de déboguer localement, utilisez une chaîne telle que la suivante :
c:\Debuggers\windbg.exe
Ne choisissez pas cette option si vous exécutez Windows Vista ou une version ultérieure de Windows.
Si vous envisagez d’utiliser le débogage à distance, spécifiez NTSD avec l’option -noio. Cela entraîne l’exécution de NTSD sans console de sa propre, accessible uniquement via la connexion à distance. Par exemple:
c:\Debuggers\ntsd.exe -server ServerTransport -noio -y SymbolPath
Si votre session de débogage commence avant que Windows ne soit entièrement chargé, vous ne pourrez peut-être pas accéder aux symboles à partir d’un partage distant ; dans ce cas, vous devez utiliser des symboles locaux. ServerTransport doit spécifier un protocole de transport implémenté par le noyau Windows sans interagir avec un service en mode utilisateur, tel que TCP ou NPIPE. Pour connaître la syntaxe de serverTransport, consultez Activation d’un serveur de débogage.
Si vous envisagez de contrôler le débogueur en mode utilisateur à partir d’un débogueur en mode noyau, spécifiez NTSD avec l’option -d. Par exemple:
c:\Debuggers\ntsd.exe -d -y SymbolPath
Si vous envisagez d’utiliser cette méthode et que vos symboles en mode utilisateur sont accessibles à partir d’un serveur de symboles, vous devez combiner cette méthode avec le débogage à distance. Dans ce cas, spécifiez NTSD avec l’option -ddefer. Choisissez un protocole de transport implémenté par le noyau Windows sans interagir avec un service en mode utilisateur, tel que TCP ou NPIPE. Par exemple:
c:\Debuggers\ntsd.exe -server ServerTransport -ddefer -y SymbolPath
Pour davantage d'informations, référez-vous à la section Contrôle du débogueur en mode utilisateur à partir du débogueur du noyau.
Une fois cette modification du Registre terminée, le débogueur est lancé chaque fois qu’un service portant ce nom est démarré ou redémarré.
Permettre à l'application de service d'accéder au débogueur
Si vous souhaitez que l'application de service bascule vers le débogueur en cas de crash ou d'exception, cette étape préliminaire est indispensable. Elle s'avère également nécessaire si vous désirez que l'application de service entre dans le débogueur via un appel à la fonction DebugBreak.
Remarque Si vous avez activé le débogage du code d’initialisation (l’étape décrite dans la sous-section « Activation du débogage du code d’initialisation »), vous devez ignorer cette étape. Lorsque le débogage du code d’initialisation est activé, le débogueur s’attache à l’application de service au démarrage, ce qui fait que tous les plantages, exceptions et appels à DebugBreak sont routés vers le débogueur sans qu'aucune préparation supplémentaire ne soit nécessaire.
Cette préparation consiste à enregistrer le débogueur sélectionné en tant que débogueur post mortem. Pour ce faire, utilisez les options -iae ou -iaec sur la ligne de commande du débogueur. Nous préconisons l'utilisation des commandes suivantes, mais en cas de modification souhaitée, veuillez consulter la syntaxe détaillée dans la section Activation du débogage post mortem.
Si vous envisagez de déboguer localement, utilisez une commande telle que :
windbg -iae
Ne choisissez pas cette option si vous exécutez Windows Vista ou une version ultérieure de Windows.
Si vous envisagez d’utiliser le débogage à distance, spécifiez NTSD avec l’option -noio. Cela entraîne l’exécution de NTSD sans console de sa propre, accessible uniquement via la connexion à distance. Pour intégrer un débogueur post mortem incluant le paramètre -server, il est impératif de modifier manuellement le registre ; consultez pour cela la section correspondante dans Activation du débogage post mortem. À titre d'exemple, la valeur Debugger de la clé AeDebug pourrait se présenter comme suit :
ntsd -server npipe:pipe=myproc%x -noio -p %ld -e %ld -g -y SymbolPath
Dans la spécification du canal de communication, le jeton %x est remplacé par l'ID du processus initiateur du débogueur. Cela garantit que, si plusieurs processus déclenchent un débogueur post mortem, chacun d'eux disposera d'un nom de tuyau unique. Si votre session de débogage commence avant que Windows ne soit entièrement chargé, vous ne pourrez peut-être pas accéder aux symboles à partir d’un partage distant ; dans ce cas, vous devez utiliser des symboles locaux. ServerTransport doit spécifier un protocole de transport implémenté par le noyau Windows sans interagir avec un service en mode utilisateur, tel que TCP ou NPIPE. Pour connaître la syntaxe de serverTransport, consultez Activation d’un serveur de débogage.
Si vous envisagez de contrôler le débogueur en mode utilisateur à partir d’un débogueur en mode noyau, spécifiez NTSD avec l’option -d. Par exemple:
ntsd -iaec -d -y SymbolPath
Si vous choisissez cette méthode et envisagez d’accéder aux symboles en mode utilisateur à partir d’un serveur de symboles, vous devez combiner cette méthode avec le débogage à distance. Dans ce cas, spécifiez NTSD avec l’option -ddefer. Choisissez un protocole de transport implémenté par le noyau Windows sans interagir avec un service en mode utilisateur, tel que TCP ou NPIPE. Pour intégrer un débogueur post mortem incluant le paramètre -server, il est impératif de modifier manuellement le registre ; consultez pour cela la section correspondante dans Activation du débogage post mortem. À titre d'exemple, la valeur Debugger de la clé AeDebug pourrait se présenter comme suit :
ntsd -server npipe:pipe=myproc%x -ddefer -p %ld -e %ld -g -y SymbolPath
Pour davantage d'informations, référez-vous à la section Contrôle du débogueur en mode utilisateur à partir du débogueur du noyau.
Lors de l'exécution de l'une de ces commandes, le débogueur post mortem est correctement enregistré. Ce débogueur est lancé chaque fois qu’un programme en mode utilisateur, y compris une application de service, rencontre une exception ou exécute une fonction DebugBreak.
Réglage du délai d'attente de l'application de service
Si vous envisagez de lancer automatiquement le débogueur (soit lorsque le service démarre ou lorsqu’il rencontre une exception), cette étape préparatoire est requise.
Recherchez la clé de Registre suivante :
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
Sous cette clé, recherchez ou créez une valeur de données DWORD appelée ServicesPipeTimeout. Définissez cette entrée sur la durée en millisecondes que vous souhaitez que le service attende avant l’expiration du délai d’attente. Par exemple, une valeur de 60 000 est d’une minute, tandis qu’une valeur de 86 400 000 est de 24 heures. Lorsque cette valeur de Registre n’est pas définie, le délai d’expiration par défaut est d’environ trente secondes.
L’importance de cette valeur réside dans le fait qu’une horloge commence à s’exécuter lorsque chaque service est lancé, et qu’une fois la valeur du délai d’expiration atteinte, tout débogueur attaché au service est interrompu. Par conséquent, la valeur que vous choisissez doit être supérieure au temps total écoulé entre le lancement du service et la fin de votre session de débogage.
Ce paramètre s’applique à chaque service démarré ou redémarré une fois la modification du Registre terminée. Si certains services se bloquent ou cessent de répondre et que ce paramètre est toujours en vigueur, le problème n’est pas détecté par Windows. Par conséquent, vous devez utiliser ce paramètre uniquement pendant le débogage et renvoyer la clé de Registre à sa valeur d’origine une fois votre débogage terminé.
Isolement du Service
Parfois, plusieurs services sont combinés dans un seul processus hôte de service (Svchost). Si vous souhaitez déboguer un tel service, vous devez d’abord l’isoler dans un processus Svchost distinct.
Il existe trois méthodes par lesquelles vous pouvez isoler un service. Microsoft recommande le déplacement du service vers sa propre méthode de groupe, comme suit. Les autres méthodes (modification du type de service et duplicating du fichier binaire SvcHost) peuvent être utilisées temporairement pour le débogage, mais parce qu’elles modifient la façon dont le service s’exécute, elles ne sont pas aussi fiables que la première méthode.
méthode préférée : déplacement du service vers son propre groupe
Émettez la commandeSc.exe( Service Configuration tool) suivante, où ServiceName est le nom du service :
sc qc ServiceName
Cela affiche les valeurs de configuration actuelles pour le service. La valeur d’intérêt est BINARY_PATH_NAME, qui spécifie la ligne de commande utilisée pour lancer le programme de contrôle de service. Dans ce scénario, étant donné que votre service n’est pas encore isolé, cette ligne de commande inclut un chemin d’accès de répertoire, Svchost.exeet certains paramètres SvcHost, y compris le commutateur -k, suivi d’un nom de groupe. Par exemple, il peut ressembler à ceci :
%SystemRoot%\System32\svchost.exe -k LocalServiceNoNetwork
N’oubliez pas ce chemin et le nom du groupe ; ils sont utilisés aux étapes 5 et 6.
Recherchez la clé de Registre suivante :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost
Créez une valeur de REG_MULTI_SZ avec un nom unique (par exemple, TempGrp).
Définissez cette nouvelle valeur égale au nom du service que vous souhaitez isoler. N’incluez pas de chemin d’accès au répertoire ou d’extension de nom de fichier. Par exemple, vous pouvez définir la nouvelle valeur TempGrp égale à MyService.
Sous la même clé de Registre, créez une clé portant le même nom que celui que vous avez utilisé à l’étape 2. Par exemple:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\TempGrp
À présent, la clé SvcHost contient une valeur portant le nouveau nom et possède également une clé subordonnée portant ce même nom.
Recherchez une autre clé subordonnée à la clé SvcHost portant le même nom que le groupe que vous avez trouvé à l’étape 1. Si une telle clé existe, examinez toutes les valeurs qu’elle contient et créez des doublons dans la nouvelle clé que vous avez créée à l’étape 4.
Par exemple, l’ancienne clé peut être nommée ceci :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\LocalServiceNoNetwork
et il peut contenir des valeurs telles que CoInitializeSecurityParam, AuthenticationCapabilitieset d’autres valeurs. Vous accédez à la clé nouvellement créée :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\TempGrp
et créez des valeurs qui sont identiques dans le nom, le type et les données à celles de l’ancienne clé.
Si l’ancienne clé n’existe pas, vous n’avez pas besoin de créer une clé.
Utilisez la commande d’outil De configuration de service suivante pour réviser le chemin d’accès trouvé à l’étape 1 :
sc config ServiceName binPath= "RevisedPath"
Dans cette commande, ServiceName est le nom du service, et RevisedPath est la nouvelle valeur que vous fournissez pour BINARY_PATH_NAME. Pour RevisedPath, reprenez scrupuleusement le chemin spécifié à l'étape 1, avec toutes les options affichées, en ne procédant qu'à une seule modification : remplacez le paramètre suivant le commutateur -k par le nom de la nouvelle valeur de registre créée à l'étape 2. Encadrez RevisedPath par des guillemets. L'espace après le signe égal est nécessaire.
Par exemple, votre commande peut ressembler à ceci :
sc config MyService binPath= "%SystemRoot%\System32\svchost.exe -k TempGrp"
Vous pouvez utiliser à nouveau la commande
sc qc pour passer en revue la modification que vous avez apportée.
Ces paramètres prennent effet la prochaine fois que le service est démarré. Pour effacer les effets de l’ancien service, nous vous recommandons de redémarrer Windows plutôt que de simplement redémarrer le service.
Une fois que vous avez terminé votre débogage, si vous souhaitez renvoyer ce service à l’hôte de service partagé, utilisez à nouveau la configuration sc sc commande pour renvoyer le chemin binaire à sa valeur d’origine et supprimer les nouvelles clés et valeurs de Registre que vous avez créées..
méthode alternative : modification du type de service
Émettez la commandeSc.exe( Service Configuration tool) suivante, où ServiceName est le nom du service :
sc config ServiceName type= own
L'espace après le signe égal est requis.
Redémarrez le service à l’aide des commandes suivantes :
net stop ServiceName net start ServiceName
Cette alternative n’est pas la méthode recommandée, car elle peut modifier le comportement du service. Si vous utilisez cette méthode, utilisez la commande suivante pour rétablir le comportement normal après avoir terminé votre débogage :
sc config ServiceName type= share
Méthode Alternative : Dupliquer le binaire SvcHost
Le fichier exécutable Svchost.exe se trouve dans le répertoire system32 de Windows. Créez une copie de ce fichier, nommez-le svhost2.exeet placez-le également dans le répertoire system32.
Émettez la commandeSc.exe( Service Configuration tool) suivante, où ServiceName est le nom du service :
sc qc ServiceName
Cette commande affiche les valeurs de configuration actuelles du service. La valeur d’intérêt est BINARY_PATH_NAME, qui spécifie la ligne de commande utilisée pour lancer le programme de contrôle de service. Dans ce scénario, étant donné que votre service n’est pas encore isolé, cette ligne de commande inclut un chemin d’accès de répertoire, Svchost.exe, et probablement certains paramètres SvcHost. Par exemple, il peut ressembler à ceci :
%SystemRoot%\System32\svchost.exe -k LocalServiceNoNetwork
Pour réviser ce chemin d’accès, exécutez la commande suivante :
sc config ServiceName binPath= "RevisedPath"
Dans cette commande, ServiceName est le nom du service, et RevisedPath est la nouvelle valeur que vous fournissez pour BINARY_PATH_NAME. Pour RevisedPath, utilisez le même chemin que celui affiché à l’étape 2, y compris toutes les options affichées sur cette ligne, en apportant une seule modification : remplacer Svchost.exe par Svchost2.exe. Placez "RevisedPath" entre guillemets. Un espace après le signe égal est requis.
Par exemple, votre commande peut ressembler à ceci :
sc config MyService binPath= "%SystemRoot%\System32\svchost2.exe -k LocalServiceNoNetwork"
Vous pouvez utiliser la commande sc qc à nouveau pour passer en revue la modification que vous avez apportée.
Redémarrez le service à l’aide des commandes suivantes :
net stop ServiceName net start ServiceName
Cette alternative n’est pas la méthode recommandée, car elle peut modifier le comportement du service. Si vous utilisez cette méthode, utilisez la commande sc config pour rétablir le chemin à sa valeur d'origine après le débogage.