Dela via


Felsöka enhetsinstallationer med KD (Kernel Debugger)

Från och med Windows Vista, när PnP-hanteraren (Plug and Play) identifierar en ny enhet i systemet, startar operativsystemet värdprocessen för enhetsinstallation (DrvInst.exe) för att söka efter och installera en drivrutin för enheten.

Eftersom enhetsinstallation sker i den här processen i användarläge är det vanligtvis enklast att använda ett felsökningsprogram i användarläge enligt beskrivningen i Felsökning av enhetsinstallationer med ett felsökningsprogram i användarläge. I vissa fall kan det dock vara bra att använda kernelfelsökaren (KD) för att övervaka installationsprocessen för enheten i användarläge.

Om du till exempel använder KD när du felsöker enhetsinstallationen i användarläge kan du göra följande:

  • Felsök samtidigt ett kernellägesproblem med hjälp av !devnode, !devobj, !drvobj, !irp och andra KD-tillägg.

  • Övervaka andra processer i användarläge utan att hantera flera felsökningsprogram med hjälp av KD-tilläggen !process eller .process /p.

Mer information om KD och andra felsökningsverktyg finns i Windows-felsökning.

Registervärdet DebugInstall anger vilken typ av stöd för felsökning av enhetsinstallation som är aktiverat i systemet. Mer information om det här registervärdet finns i Aktivera stöd för felsökning av enhetsinstallationer.

När registervärdet DebugInstall är inställt på 1 kontrollerar DrvInst.exe först att kernelfelsökaren både är aktiverad och ansluten innan den bryter sig in i felsökningsprogrammet. När den här pausen har gjorts kan brytpunkter anges i modulerna i användarläge i den aktuella processen. Till exempel:

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

Detta anger en brytpunkt på rutinen SETUPAPI!SetupDiCallClassInstaller för endast den aktuella processen.

För utvecklaren av ett drivrutinspaket är det vanligtvis mest önskvärt att felsöka åtgärderna för en klassinstallation eller DLL för co-installer under installationen av en enhet. Men när DrvInst.exe bryter sig in i felsökningsprogrammet har alla DLL:er för klassinstallationer eller co-installer från drivrutinspaketet inte lästs in. Även om felsökarna i användarläge stöder möjligheten att ange ett felsökarfel när en modul i användarläge läses in i processen med kommandot "sx e ld" stöder kernelfelsökaren endast moduler i kernelläge med det kommandot.

I följande kodexempel visas hur ett "Debugger Command Program" övervakar inläsningen av en specifik klassinstallation eller ett saminstallationsprogram i den aktuella processen. I det här exemplet anger kommandoprogrammet för felsökaren en brytpunkt på huvudstartpunkten (CoInstallerProc) för Mycoinst.dll co-installer:

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]}

När det utförs kontrollerar felsökningskommandoprogrammet listan över moduler som har lästs in i den aktuella processen för Mycoinst.dll. När DLL:n för det här saminstallationsprogrammet har lästs in anger felsökaren en brytpunkt (med ett välkänt brytpunkts-ID) i startpunktsfunktionen CoInstallerProc.

Från och med felsökningspausen som initierades av DrvInst.exe värdprocessen bör du först ange en brytpunkt på returadressen för samtalet där DrvInst.exe bröt sig in i kernelfelsökaren. Den här brytpunkten kommer att rensa alla brytpunkter som har ställts in under enhetsinstallationen och sedan fortsätta processen:

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"

Därefter bör du ange några brytpunkter i processen så att kommandona i felsökningsprogrammet kan köras vid lämplig tidpunkt under enhetsinstallationen.

För att säkerställa att brytpunkten för klassinstallationsprogrammet eller DLL-startpunkten för co-installer har angetts innan funktionen anropas för enhetsinstallation, ska felsökningsprogrammet köras när en ny DLL läses in i den aktuella processen, det vill säga efter att ett anrop till LoadLibraryExW returnerar:

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

I stället för att köra programmet på varje LoadLibraryEx-anrop i processen (bp[0x10]), kan utvecklaren begränsa det till att endast köras när klassinstallations- och medinstallations-DLL:er laddas in i processen. Eftersom SetupDiCallClassInstaller är den rutin som anropar klassinstallationsprogram och saminstallationer som är registrerade för en enhet, läses dessa DLL:er in i processen under det anropet.

Eftersom inga antaganden bör göras om när dessa DLL:er kommer att tas bort från DrvInst.exe värdprocessen, måste du se till att brytpunkterna kan hantera lokalisering av DLL-startpunkter under alla anrop som görs till SetupDiCallClassInstaller från DrvInst.exe värdprocess.

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

Brytpunkten för att köra felsökningskommandot (bp[0x10]) är initialt inaktiverad. Den aktiveras när SetupDiCallClassInstaller anropas (bp[0x11]) och körningen fortsätter. Kommandoprogrammet för felsökning (bp[0x10]) inaktiveras igen när SetupDiCallClassInstaller returnerar genom att ange en brytpunkt på själva returadressen för den rutinen (bp[0x12]).

Tänk på att brytpunkten som inaktiverar kommandoprogrammet för felsökning också rensar sig själv och fortsätter att köras tills SetupDiCallClassInstaller anropas igen eller tills installationsprogrammet har slutförts och alla brytpunkter har rensats (bp[0x13]).

När körningen börjar efter att ovanstående brytpunkter har angetts kommer processen att stanna för varje anrop till mycoinst!CoInstallerProc. På så sätt kan du felsöka körningen av klassinstallationsprogrammet eller DLL:n för co-installer under installationen av kärnenheten.

Standardtiden för en installationsprocess som ska slutföras är 5 minuter. Om processen inte slutförs inom den angivna tidsperioden förutsätter systemet att processen har slutat svara och att den avslutas.

Standardbegränsningen för timeout som placeras på enhetsinstallationer gäller fortfarande medan processen debuggas via kernelfelsökaren. Eftersom körningen av alla program i systemet stoppas när systemet bryts upp för felsökning, spåras tiden det tar för installationsprocessen på samma sätt som på ett system som inte felsöks.