Compartilhar via


Depurando componentes do driver da impressora

Se você estiver desenvolvendo um plug-in de renderização de driver de impressora ou plug-in de interface do usuário, poderá habilitar mensagens de depuração nesses componentes. Conforme explicado na seção Variável de Depuração Global, você pode usar uma variável de depuração global para controlar o nível de detalhes em mensagens que aparecem na janela do depurador.

Você pode usar as macros discutidas na seção Macros de Mensagem de Depuração para enviar mensagens para a janela do depurador em uma variedade de condições. Além disso, você pode usar as informações nesta seção para habilitar mensagens de depuração nos renderizadores do Driver de Impressora Universal da Microsoft (Unidrv) ou do Driver de Impressora PostScript (Pscript), desde que você tenha verificado builds dessas DLLs.

Observação

Os builds verificados estavam disponíveis em versões mais antigas do Windows, antes de Windows 10 versão 1803. Use ferramentas como Driver Verifier e GFlags para marcar código de driver em versões posteriores do Windows.

As etapas para depurar um driver de modo de usuário e algumas dicas gerais de depuração são incluídas nas próximas duas seções.

Preparando-se para depuração de User-Mode

Para iniciar a depuração de drivers de impressora e seus componentes:

  1. Instale as ferramentas de depuração mais recentes. Confira Baixar Ferramentas de Depuração para Windows

  2. Instalar os símbolos corretos dos Pacotes de Símbolos do Windows

Observação

É muito importante que você use a versão mais recente do depurador.

É aconselhável instalar o build verificado somente dos componentes que você está interessado em depurar. Normalmente, você substituiria os seguintes binários de varejo por seus builds verificados correspondentes:

  • Unidrv.dll

  • Unidrvui.dll

  • Unires.dll

Você também deve instalar o build verificado do exemplo Oemuni ou do driver de impressora que você está depurando. A vantagem de usar essa abordagem, em vez de instalar um sistema de build verificado inteiro, é que você não reduzirá a velocidade de todo o sistema.

Iniciando uma sessão de depuração de User-Mode

Para iniciar a depuração do modo de usuário, no menu Arquivo no depurador Windbg, selecione Anexar a um processo. O processo ao qual você anexa o depurador depende do cenário que você está tentando depurar. Para drivers de impressora, você deve anexar o depurador ao aplicativo de impressão ou ao processo de spooler (Spoolsv.exe). Tenha em mente que o aplicativo de impressão carrega o módulo de configuração/interface do usuário, enquanto o processo de spooler carrega o módulo de renderização. No entanto, há diferenças para impressão "FILE:", em que o spooling não ocorre e, como resultado, o módulo de renderização também é carregado pelo aplicativo de impressão. Portanto, você deve garantir que você anexe ao processo correto.

Observação

Você não precisa de dois computadores separados para depuração no modo de usuário.

O procedimento a seguir preparará você para depurar o exemplo de Oemuni.

  1. Instale o exemplo Oemuni na porta "FILE:".

  2. Inicie o aplicativo WordPad clicando no menu Iniciar , selecionando Todos os Programas, selecionando Acessórios e, em seguida, selecionando WordPad.

  3. No menu Arquivo WinDbg, selecione Anexar a um Processo. Na lista de processos disponíveis, selecione WordPad.exe.

  4. Inicie um trabalho de impressão no WordPad. Agora você está pronto para depurar o exemplo Oemuni.

Você pode habilitar a depuração detalhada ativando a variável giDebugLevel. Seu valor padrão é 3, que indica WARNING. Se definido como 1, ele denota VERBOSE. Para definir o último valor com Unidrv.dll, digite o seguinte comando no depurador:

> ed unidrv!giDebugLevel 1

Quando você estiver executando o exemplo Oemuni, a mesma variável de depuração também se aplica, portanto, para habilitar a depuração detalhada, digite o seguinte comando:

> ed oemuni!giDebugLevel 1

Você também pode adicionar suas próprias instruções de depuração ao exemplo Oemuni.

Para obter mais informações sobre como definir valores de depuração, consulte a documentação do WinDbg, que descreve os comandos disponíveis e as etapas de estrutura de tópicos necessárias para configurar a depuração no modo de usuário. Para acessar a documentação, no menu Ajuda do WinDbg, selecione Conteúdo.

Variável de depuração global

A variável global giDebugLevel é declarada pelos exemplos Oemui e Oemuni em seus arquivos Debug.h e Debug.cpp. O valor de giDebugLevel pode ser modificado por:

  • Alterando seu valor no depurador
  • Redefinindo seu valor no plug-in

Você pode definir giDebugLevel como qualquer um dos seguintes valores:

#define DBG_VERBOSE 1
#define DBG_TERSE   2
#define DBG_WARNING 3
#define DBG_ERROR   4
#define DBG_RIP     5

Macros de mensagem de depuração

As macros a seguir são usadas para fins de depuração. Vários deles tomarão medidas somente se a variável global giDebugLevel, que controla quais mensagens de depuração são emitidas, estiver definida como um valor específico. As macros se expandem para espaços em branco em uma compilação gratuita. Aqui estão breves descrições do que eles fazem e seus parâmetros.

ASSERT(cond)

  • Verifica se a expressão booliana em cond é TRUE. Se não estiver, a macro forçará um ponto de interrupção.

ASSERTMSG(cond, (msg))

  • Verifica se a expressão booliana em cond é TRUE. Se não estiver, a macro exibirá a mensagem em msg e forçará um ponto de interrupção.

ERR((msg))

  • Exibe a mensagem em msg se o nível de depuração atual for <= DBG_ERROR. O formato da mensagem é:

    ERR filename (linenumber): msg
    

RIP((msg))

  • Exibe a mensagem em msg e força um ponto de interrupção.

TERSE((msg))

  • Exibe a mensagem em msg se o nível de depuração atual for <= DBG_TERSE.

VERBOSE((msg))

  • Exibe a mensagem em msg se o nível de depuração atual for <= DBG_VERBOSE.

WARNING((msg))

  • Exibe a mensagem em msg se o nível de depuração atual for <= DBG_WARNING. O formato da mensagem é:

    WRN filename (linenumber): msg
    

Observe que todas as macros com um argumento msg exigem um par extra de parênteses em torno desse argumento. Aqui estão dois exemplos que ilustram esse requisito:

ASSERTMSG(x > 0, ("x is less than 0\n"));
WARNING( ("App passed NULL pointer, ignoring...\n") );

As macros que contêm um argumento msg são definidas pelos exemplos Oemui e Oemuni em seus cabeçalhos Debug.h.