Partager via


Débogage des installations d’appareils avec le débogueur de noyau (KD)

À compter de Windows Vista, lorsque le gestionnaire Plug-and-Play (PnP) détecte un nouvel appareil dans le système, le système d’exploitation démarre le processus hôte d’installation de l’appareil (DrvInst.exe) pour rechercher et installer un pilote pour l’appareil.

Étant donné que l’installation de l’appareil se produit dans ce processus en mode utilisateur, il est généralement plus facile d’utiliser un débogueur en mode utilisateur, comme décrit dans Débogage des installations d’appareils avec un débogueur en mode utilisateur. Dans certains cas, toutefois, il peut être utile d’utiliser le débogueur de noyau (KD) pour surveiller le processus d’installation de l’appareil en mode utilisateur.

Par exemple, en utilisant KD lors du débogage de l’installation d’appareil en mode utilisateur, vous pouvez effectuer les opérations suivantes :

  • Déboguez simultanément un problème en mode noyau à l’aide de !devnode, !devobj, !drvobj, !irp et d’autres extensions KD.

  • Surveillez d’autres processus en mode utilisateur sans gérer plusieurs débogueurs à l’aide des extensions KD !process ou .process /p.

Pour plus d’informations sur KD et d’autres outils de débogage, consultez Débogage Windows.

La valeur de Registre DebugInstall spécifie le type de prise en charge du débogage de l’installation de l’appareil activée sur le système. Pour plus d’informations sur cette valeur de Registre, consultez Activation de la prise en charge pour le débogage des installations d’appareils.

Lorsque la valeur de Registre DebugInstall est définie sur 1, DrvInst.exe commencez par case activée que le débogueur du noyau est activé et actuellement attaché avant qu’il ne se brise dans le débogueur. Une fois cette interruption effectuée, des points d’arrêt peuvent être définis dans les modules en mode utilisateur du processus actuel. Par exemple :

kd> .reload /user
kd> bp /p @$proc setupapi!SetupDiCallClassInstaller

Cela définit un point d’arrêt sur la routine SETUPAPI ! SetupDiCallClassInstaller pour le processus en cours uniquement.

Pour le développeur d’un package de pilotes, il est généralement plus souhaitable de déboguer les actions d’un programme d’installation de classe ou d’une DLL de co-programme d’installation pendant l’installation d’un appareil. Toutefois, lorsque DrvInst.exes’insère dans le débogueur, les DLL du programme d’installation ou de co-programme d’installation de classe à partir du package de pilotes n’ont pas été chargées. Bien que les débogueurs en mode utilisateur prennent en charge la possibilité de définir une exception de débogueur lorsqu’un module en mode utilisateur est chargé dans le processus avec la commande « sx e ld », le débogueur du noyau prend uniquement en charge les modules en mode noyau avec cette commande.

L’exemple de code suivant montre comment un « Programme de commandes de débogueur » surveille le chargement d’un programme d’installation ou d’un co-programme d’installation de classe spécifique dans le processus en cours. Dans cet exemple, le programme de commandes du débogueur définit un point d’arrêt sur le point d’entrée main (CoInstallerProc) du co-programme d’installationMycoinst.dll :

file: Z:\bpcoinst.txt

r $t1 = 0
!for_each_module .if ($spat("@#ModuleName", "mycoinst*") = 0) {r $t1 = 1}
.if (not @$t1 = 0) {.echo mycoinst is loaded, set bp on mycoinst!CoInstallerProc } .else {.echo mycoinst not loaded}
.if (not @$t1 = 0) {.reload mycoinst.dll}
.if (not @$t1 = 0) {bp[0x20] /p @$proc mycoinst!CoInstallerProc } .else {bc[0x20]}

Lorsqu’il est exécuté, le programme de commandes du débogueur case activée la liste des modules chargés dans le processus actuel pour Mycoinst.dll. Une fois cette DLL de co-programme d’installation chargée, le débogueur définit un point d’arrêt (avec un ID de point d’arrêt connu) sur la fonction de point d’entrée CoInstallerProc.

À partir de l’arrêt de débogage initié par le processus hôte DrvInst.exe , vous devez d’abord définir un point d’arrêt sur l’adresse de retour de l’appel où DrvInst.exes’est introduit dans le débogueur du noyau. Ce point d’arrêt efface tous les points d’arrêt définis pendant l’installation de l’appareil et poursuit l’exécution :

DRVINST.EXE: Entering debugger during PnP device installation.
Device instance = "X\Y\Z" ...

Break instruction exception - code 80000003 (first chance)
010117b7 cc               int     3

kd> bp[0x13] /p @$proc @$ra "bc *;g"

Ensuite, vous devez définir des points d’arrêt dans le processus pour permettre aux commandes du programme de commandes du débogueur de s’exécuter au moment approprié pendant l’installation de l’appareil.

Pour vous assurer que le point d’arrêt du programme d’installation de classe ou du point d’entrée de la DLL de co-programme d’installation est défini avant que la fonction soit appelée pour l’installation de l’appareil, le programme de commande du débogueur doit être exécuté chaque fois qu’une nouvelle DLL est chargée dans le processus actuel, c’est-à-dire après qu’un appel à LoadLibraryExW retourne :

kd> .reload
kd> bp[0x10] /p @$proc kernel32!LoadLibraryExW "gu;$$><Z:\\bpcoinst.txt;g"

Au lieu d’exécuter le programme sur chaque appel LoadLibraryEx au sein du processus (bp[0x10]), le développeur peut le limiter à l’exécution uniquement lorsque le programme d’installation de classe et les DLL de co-programme d’installation sont chargées dans le processus. Étant donné que SetupDiCallClassInstaller est la routine qui appelle les programmes d’installation de classe et les co-programmes d’installation inscrits pour un appareil, ces DLL seront chargées dans le processus pendant cet appel.

Étant donné qu’aucune hypothèse ne doit être faite quant au moment où ces DLL seront déchargées du processus hôte DrvInst.exe , vous devez vous assurer que les points d’arrêt peuvent gérer la localisation des points d’entrée dll pendant les appels effectués à SetupDiCallClassInstaller à partir du processus hôte DrvInst.exe .

kd> bd[0x10]
kd> bp[0x11] /p @$proc setupapi!SetupDiCallClassInstaller "be[0x10];bp[0x12] /p @$proc @$ra \"bd[0x10];bc[0x12];g\";g"
kd> g

Le point d’arrêt pour exécuter le programme de commande du débogueur (bp[0x10]) est initialement désactivé. Il est activé chaque fois que SetupDiCallClassInstaller est appelé (bp[0x11]) et l’exécution continue. Le programme de commande du débogueur (bp[0x10]) est à nouveau désactivé lorsque SetupDiCallClassInstaller retourne en définissant un point d’arrêt sur l’adresse de retour de cette routine elle-même (bp[0x12]).

N’oubliez pas que le point d’arrêt qui désactive le programme de commande du débogueur s’efface lui-même et continue l’exécution jusqu’à ce que SetupDiCallClassInstaller soit appelé à nouveau ou jusqu’à ce que le programme d’installation se termine et que tous les points d’arrêt soient effacés (bp[0x13]).

Lorsque l’exécution commence après que les points d’arrêt ci-dessus sont définis, le processus s’interrompt à chaque appel à mycoinst! CoInstallerProc. Cela vous permet de déboguer l’exécution du programme d’installation de classe ou de la DLL de co-programme d’installation pendant l’installation de l’appareil principal.

La période par défaut d’exécution d’un processus d’installation est de 5 minutes. Si le processus ne se termine pas au cours de la période donnée, le système suppose que le processus a cessé de répondre et qu’il est terminé.

La restriction de délai d’attente par défaut appliquée aux installations de l’appareil est toujours en vigueur pendant que le processus est en cours de débogage via le débogueur du noyau. Étant donné que l’exécution de tous les programmes sur le système est arrêtée lors d’une panne dans le débogueur, le temps nécessaire au processus d’installation est suivi de la même manière que sur un système qui n’est pas débogué.