Como assim eu não gosto de tela azul?

3 de September de 2007 - Fernando Roberto

Não que eu morra de alegria toda vez que vejo uma. Tela azul é um sinal de que algo errado aconteceu, mas melhor você tê-la visto que um cliente seu ligar dizendo que viu uma. Por isso, precisamos fazer a maior força para que elas aconteçam. Já vi programadores fugirem da tela azul tentando se esconder atrás de um manipulador de exceções. Acho que não preciso dizer que isso é tapar o sol com a peneira. Desta forma você apenas deixa de encontrar agora os erros que você ou alguém vai encontrar daqui a algum tempo, até lá, os micros que estão utilizando seus drivers podem ter uma reinicialização repentina aqui ou alí. Mas telas azuis acontecem mesmo, é tudo uma questão de sorte, só que seus clientes podem perceber que usar os seus drivers dá o maior azar. Neste post, vou dar algumas dicas de como podemos ver mais telas azuis em nossos testes de drivers.

Uma passada de F8

Não entenda isso como “Teste você mesmo”, mas entenda por testar todos os códigos de retorno que você puder. Lembre-se que se algo der errado, não será apenas mais um MessageBox que vai aparecer, mas normalmente quando as coisas tomam esse rumo, tudo termina em azul, mais cedo ou mais tarde. Vamos torcer pelo mais cedo. Costumo dizer que todo código merece pelo menos uma passada de F8, que é a minha tecla de Step into. É, eu sei que é diferente do normal, mas quando comecei a utilizar o Visual C/C++ 1.52, o layout do teclado era esse. Mas voltando ao ponto, certa vez eu fiz uma função que deveria simplesmente ler um arquivo, e na minha passada de F8 recebi um código de retorno que não era STATUS_SUCCESS, mas passou na macro NT_SUCCESS(). A pressa me fez ignorar aquilo, afinal não era um erro, era apenas um aviso. Semanas depois, a equipe de teste me disse que por algum motivo o driver estava retornando lixo na leitura do arquivo. Um pouco de debug me voltou a mostrar aquele mesmo código de retorno. Foi só depois de olhar a sua definição no arquivo ntstatus.h que entendi tudo.

//
// MessageId: STATUS_PENDING
//
// MessageText:
//
//  The operation that was requested is pending completion.
//
#define STATUS_PENDING                   ((NTSTATUS)0x00000103L)    // winnt

Enquanto depurando, o sistema tem tempo suficiente para fazer o I/O que ficou para depois, mas quando botamos o bixo pra correr a história é outra.

Um código que passou no seu teste de F8 rodará nos mais diversos ambientes existentes e imagináveis. Logo, essa primeira fase serve apenas para retirar os erros mais grosseiros. Depois disso, é a equipe de testes que deveria surrar a vítima. Existem pessoas que realmente tem o dom de testar software. Trabalhei em uma empresa em que a pessoa que testava os produtos devia ter algum problema pessoal com o software que produzíamos (ou com nós, vai saber). Eu podia testar por dias, mas quando eu entregava o software para teste, não demorava meia hora para ele me ligar de volta dizendo aquela frase que já virou sua marca registrada: “Muito ruim!!!”. Não tinha explicação. Costumávamos dizer que o micro dele tinha sido formatado em cima de um cemitério indígena. Não é à toa que teste de desenvolvedor é tão mal visto.

Acerte no ASSERT

Imagino que a maioria de vocês já tenha ouvido falar na macro ASSERT. Esta macro tem a finalidade de assegurar que determinada condição seja verdadeira. Caso a condição seja falsa, uma tela azul nos salta aos olhos. Nossa, que macro incrível, ajudou muito mesmo. É, eu sei, não é bem assim. Na verdade este é o comportamente que teríamos se o depurador não estivesse atachado ao sistema. Então seria perfeito utilizar esta macro somente em Checked. Devo lembrá-los que Checked significa Debug e Free significa Release? Bom, já foi. Se dermos uma olhada em sua definição, veremos que o óbvio já foi pensado.

#if DBG
 
#define ASSERT( exp ) \
    ((!(exp)) ? \
        (RtlAssert( #exp, __FILE__, __LINE__, NULL ),FALSE) : \
        TRUE)
...
 
#else
 
#define ASSERT( exp )         ((void) 0)
 
...
 
#endif // DBG

Mas o que acontece se estivermos com o depurador atachado? Boa pergunta, essa é realmente uma pergunta interessante, fico feliz que você a tenha feito. Alguém já lhe disse que você leva jeito para programar? Enfim, eu alterei um dos nossos exemplos para forçar esta condição.

extern "C"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObj,
                     IN PUNICODE_STRING pusRegistryPath)
{
    //-f--> Eu acho que tenho certeza de que esta conta está certa.
    ASSERT(1 + 1 == 3);

Caso a condição falhe e estivermos com um debugger de Kernel atachado ao sistema, este exibirá a condição que falhou na janela de saída e nos solitará que entremos com uma das quatro alternativas como mostra abaixo.


Como vocês podem ver, o ASSERT é prático, fácil e não engorda. Ele só requer um pouquinho assim de cérebro. Digo isso porque todos nós já tivemos dias difíceis, e depois das 23h nenhum programador deveria responder por qualquer código produzido. Certa vez custou-me descobrir por que o código abaixo não funcionava adequadamente. Apesar de tudo funcionar perfeitamente bem quando compilado em Checked, parecia simplesmente que uma certa função não estava sendo chamada em Free. Se derem mais uma olhada na definição desta macro, verão que a condição desaparece quando compilada em Free, e neste caso, a chamada também.

    //-f--> Não basta querer programar, tem que pensar.
    //      << Não copie isso >>
    ASSERT(DoSomeThing() == STATUS_SUCCESS);

Um sistema em Checked

Não seria bom ter um sistema operacional inteiro repleto de ASSERTs e testes para detectar o menor sinal de problemas, e ao encontrá-lo, nos presentearia com uma bela tela azul? Bem, você provavelmente já deve ter ouvido falar das versões Checked Build. Elas são exatamente isso que acabei de escrever. Um sistema operacional inteiro compilado em Checked. Isso significa que todos os ASSERTs que estão nos fontes foram incluidos nos binários finais e estão verificando o sistema para você. Pode parecer besteira ter que instalar seu driver em um desses, mas acredite, vale a pena. Já tive drivers que funcionaram muito bem durante meses, até que meu gerente sugeriu que fossem testados em versões Checked. No topo da minha arrogância, eu pensei comigo mesmo: “Até parece que vai pegar alguma coisa”. É, vivendo e aprendendo. A máquina nem iniciava com meus drivers, era uma tela azul atrás da outra. As versões de Checked Build têm verificações até de deadlock. Você seria capaz de adivinhar o que aconteceria se algum spinlock fosse mantido por mais de um determinado tempo? Aposto que sim.

Já que as versões Ckecked Build são à prova de falhas, posso usá-las como meu sistema padrão? Poder pode, mas tudo é muito mais lento, milhares de verificações estão sendo feitas todo o tempo e o código não tem qualquer otimização aplicada. Em uma instalação do zero, sem instalar qualquer software adicional, você pode encontrar ASSERTs do Internet Explorer ou de outros programas. Isso mesmo, não é só o Kernel que está em Checked, mas todo o sistema. Você teria sempre que deixar um depurador de Kernel atachado ao seu sistema, pois o menor sinal de fumaça seria motivo mais que suficiente para mais uma tela azul.

Se passou pelo Checked Build então o driver está perfeito? Sinto desapontá-lo. Lembre-se que o impacto de performance causado por tantos testes pode ocultar problemas como race conditions. O ideal é testar seus drivers em ambas as versões. Uma configuração permite que tenhamos apenas a imagem do sistema e a HAL em Checked enquanto que o restante do sistema fique em Free. Isso permitiria ter testes adicionais no Kernel enquanto o restante do sistema roda a versão mais leve. Este link explica como fazer isso.

Agora sim meu driver tá lindio?

Na verdade, isso ainda é só o mínimo que você deveria fazer. Uma outra excelente ferramenta geradora de telas azuis é o Driver Verifier. Este aplicativo trabalha em conjunto com o sistema para monitorar ações de uma lista de drivers composta por você. A partir do Windows 2000, o Driver Verifier já vem instalado. Experimente agora mesmo! Não requer prática e tão pouco habilidade. Na janela de “Run…” do Windows, digite “Verifier” e um simples Wizard será iniciado. Como pretendo terminar este post ainda nesta vida, não vou descrever passo a passo como utilizar esta ferramenta, mas existem vários links na página do produto que podem te ajudar nisso.

Vai gostar de tela azul assim no inferno!

Para se ter uma idéia de como a busca por telas azuis é importante para uma companhia de software, a Microsoft promove o IFS Plug Fest com o intuito de testar a interoperabilidade de diversos produtos que implementam File Systems ou filtros para eles. O evento é gratuito, mas cada compania deve arcar com as despesas de viagem e estadia de seus representantes. Nestes encontros, os profissionais do mundo todo reunem-se para fazer os testes entre si além de poder ter o contato e tirar possíveis dúvidas a respeito deste complexo modelo de desenvolvimento. São também promovidos seminários que discutem os problemas comuns enfrentados por esta comunidade. Ainda não estive em um desses, mas um dia quem sabe.

Calma, ainda tem mais

Além das ferramentas aqui citadas, existem outras que eu não poderia deixar de citar. Mas não vou me prolongar em explicar como cada uma delas funciona.

  • Prefast – Ferramenta que faz análize dos fontes a serem compilados pelo DDK em busca de erros comuns de programação para drivers de Kernel.
  • Static Driver Verifier – Esta ferramenta faz uma análise estática do binário já compilado. O teste é bem mais demorado, mas obtém mais resultados que os obtidos no Prefast.
  • Hardware Compatibility Test – Conjunto de softwares que aplicam o testes para a obtenção da certificação de drivers da Microsoft. Descontinuada há pouco tempo.
  • Driver Test Manager – Este é o software sucessor do HCT para testes de certificação de drivers.

Depois de tanta tela azul, só café mesmo pra ajudar.
Até mais!

4 Responses to “Como assim eu não gosto de tela azul?”

  1. Daniele says:

    Caro Fernando,

    Essa tela azul tá muito machista!

    []´s

    Daniele.

    • Olá Daniele,

      É sempre um prazer conhecer novos leitores. Mas o que é um tando incomum é o fato de haver leitores do sexo feminino.

      Não que eu seja machista, mas de fato, a esmagadora maioria dos programadores de Kernel é do sexo masculino. Isso justifica meu comentário neste post, o qual fala sobre a presença da única mulher da sala no curso de File System que fiz em Boston.

      Enfim, como não possível agradar a todos, posso ao menos tentar agradar a esmagadora maioria.

      Fico feliz que tenha deixado este comentário. Agora posso dormir mais à vontade sabendo que não estou escrevendo apenas para um bando de machos. 🙂

      []s,

  2. thiagozildjian says:

    fala ai brother
    estive vendo umas postagens suas..
    tem como vc me add no msn pra tirar umas duvidas?
    thidream@hotmail.com
    vlw brothe

    • Olá Thiago,

      Será que conseguimos resolver suas dúvidas por e-mail?

      Mande um e-mail para fernando(at)driverentry.com.br com suas dúvidas e conversamos.

      []s,

Deixe um comentário