Depurando instalações de dispositivo com um depurador no modo de usuário
A partir do Windows Vista, quando o gerenciador de Plug and Play (PnP) detecta um novo dispositivo no sistema, o sistema operacional inicia o processo de host de instalação do dispositivo (DrvInst.exe) para pesquisar e instalar um driver para o dispositivo.
A maneira mais eficiente de depurar o processo de host de instalação do dispositivo no modo de usuário é com um depurador de modo de usuário, como WinDbg ou Visual Studio. Como o processo deDrvInst.exe normalmente seria concluído sem qualquer interação do usuário, a Microsoft adicionou suporte ao Windows Vista e versões posteriores do Windows para permitir que o desenvolvedor de um pacote de driver anexasse um depurador antes que os estágios principais da instalação do dispositivo fossem processados.
Para obter mais informações sobre depuradores de modo de usuário e outras ferramentas de depuração, consulte Depuração do Windows.
O valor de Registro DebugInstall especifica o tipo de suporte à depuração de instalação do dispositivo que está habilitado no sistema. Para obter mais informações sobre esse valor do Registro, consulte Habilitando o suporte para depuração de instalações de dispositivo.
Quando o valor do Registro DebugInstall for definido como 2, DrvInst.exe aguardará que um depurador de modo de usuário seja anexado ao processo antes de continuar com a instalação. Depois que um depurador for anexado, o processo será dividido no próprio depurador. Um depurador deve ser anexado e configurado de modo que ele não inicie seu próprio ponto de interrupção inicial no sistema de destino que está sendo depurado.
Por exemplo, um depurador pode ser anexado a DrvInst.exe por nome:
C:\>C:\Debuggers\WinDbg.exe -g -pn DrvInst.exe
Ou, se um depurador estiver anexado ao sistema de destino, as seguintes informações de depuração serão exibidas:
DRVINST.EXE: Waiting for debugger on Process ID = 3556 ......
Isso permite que o depurador seja anexado ao processo deDrvInst.exe usando sua ID de processo exclusiva:
C:\>C:\Debuggers\WinDbg.exe -g -p 3556
Depois que um depurador de modo de usuário for anexado ao processo deDrvInst.exe , o processo será dividido no depurador:
Debugger detected!
DRVINST.EXE: Entering debugger during PnP device installation.
Device instance = "X\Y\Z" ...
(d48.5a0): Break instruction exception - code 80000003 (first chance)
eax=7ffde000 ebx=00000000 ecx=00000000 edx=77f745c0 esi=00000000 edi=00000000
eip=77f24584 esp=0105ff74 ebp=0105ffa0 iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!DbgBreakPoint:
77f24584 cc int 3
0:000> |
. 0id: d48attachname: E:\Windows\system32\DrvInst.exe
Como os estágios principais da instalação do dispositivo não foram processados, nenhum instalador de classe ou DLLs de co-instalador usados para o dispositivo ainda não foram carregados.
Se o módulo e o nome da função de um ponto de interrupção forem conhecidos com antecedência, esse nome poderá ser definido como um ponto de interrupção não resolvido usando o comando "bu" do depurador. O exemplo de código a seguir mostra como definir um ponto de interrupção não resolvido para o ponto de entrada main (CoInstallerProc) do co-instalador doMyCoinst.dll:
0:000> bu mycoinst!CoInstallerProc
0:000> bl
0 eu 0001 (0001) (mycoinst!CoInstallerProc)
Quando MyCoinst.dll co-instalador é carregado e o ponto de interrupção é atingido:
Breakpoint 0 hit
eax=00000001 ebx=00000000 ecx=00000152 edx=00000151 esi=01a57298 edi=00000002
eip=5bcf54f1 esp=0007e204 ebp=0007e580 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
mycoinst!CoInstallerProc:
5bcf54f1 8bff mov edi,edi
0:000> bl
0 e 5bcf54f1 0001 (0001) 0:**** mycoinst!CoInstallerProc
Um instalador de classe ou uma DLL de co-instalador não deve prever quando, respectivamente, será carregado ou descarregado do processo deDrvInst.exe . No entanto, um ponto de interrupção definido usando "bu" permanecerá mesmo se o módulo for descarregado.
Como alternativa, o processo deDrvInst.exe pode ser executado até o ponto em que um instalador de classe específico ou DLL do co-instalador é carregado no processo definindo uma exceção de depurador para o evento de carregamento dessa DLL:
0:000> sxe ld mycoinst.dll
0:000> g
Depois que o módulo é carregado, os pontos de interrupção podem ser definidos dentro da DLL. Por exemplo:
ModLoad: 5bcf0000 5bd05000 C:\WINDOWS\system32\mycoinst.dll
eax=00000000 ebx=00000000 ecx=011b0000 edx=7c90eb94 esi=00000000 edi=00000000
eip=7c90eb94 esp=0007da54 ebp=0007db48 iopl=0 nv up ei ng nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000296
ntdll!KiFastSystemCallRet:
7c90eb94 c3 ret
0:000> .reload mycoinst.dll
0:000> x mycoinst!*InstallerProc*
5bcf54f1 mycoinst!CoInstallerProc (unsigned int, void *, struct _SP_DEVINFO_DATA *)
0:000> bu mycoinst!CoInstallerProc
0:000> bl
0 e 3b0649d5 0001 (0001) 0:**** mycoinst!CoInstallerProc
0:000> sxd ld mycoinst.dll
0:000> g
Breakpoint 0 hit
eax=00000001 ebx=00000000 ecx=000001d4 edx=000001d3 esi=000bbac0 edi=00000002
eip=5bcf54f1 esp=0007e204 ebp=0007e580 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
mycoinst!CoInstallerProc:
5bcf54f1 8bff mov edi,edi
0:000>
Como o ponto de interrupção foi definido como um ponto de interrupção não resolvido (bu), ele permanecerá definido mesmo se o módulo for descarregado.
O período de tempo padrão para que um processo de instalação seja concluído é de 5 minutos. Se o processo não for concluído dentro do período determinado, o sistema assumirá que o processo foi suspenso (parou de responder) e o processo de instalação será encerrado.
Se um depurador de modo de usuário estiver anexado ao sistema de destino durante o processo de instalação do dispositivo, o sistema não imporá esse período de tempo limite. Isso permite que um desenvolvedor de pacote de driver gaste o tempo necessário para depurar o processo de instalação.