Archive for the ‘Debug’ Category

Step into Kernel (SoftIce)

23 de December de 2006

Enfim de volta das férias. Já faziam aproximadamente seis anos que eu não tirava férias. Viajar, conhecer novos lugares e simplesmente relaxar foram minhas principais tarefas durante estes 20 dias. De volta ao trabalho, assim que cheguei na empresa, fui supreendido por ela. Eu nem acredito que mandaram aquela velha embora. Trocamos olhares e é óbvio que pintou um clima. Cheguei mais perto para poder sentir seu cheiro. Eu a olhava de cima a baixo. Simplemente perfeita e até uma injustiça deixa-la de canto. Não demorou e ela já estava sob o meu controle. Eu tinha que provar tudo aquilo. Afinal, haviam tantas opções: Café, cappuccino, chocolate, chá, com ou sem açúcar. Mas foi tudo ilusão. “Ô cafézim ruím dos inferno”. Meus amigos, as aparências enganam. Como pode uma máquina tão bonita fazer um café tão ruím? Confesso que sinto saudades da velha. Não estou querendo dizer que o café é ruinzinho porque o café é horrível! Agora estou buscando maneiras alternativas para manter meu vício. Talvez existam adesivos de cafeína para vender.

Não se preocupem, este não será mais um post Off-Topic sobre máquinas de café trocadas e o impacto causado por elas. Neste post, que comecei no ano passado e só terminei agora, vou dar os passos necessários para utilizar o SoftICE como depurador de sistema.

Eu ainda era novo na Scua e estava desenvolvendo uma GINA para o nosso produto de segurança. Para quem não sabe, GINA é aquela telinha de Logon que aparece na plataforma NT. A GINA é uma DLL que é carregada pelo processo Winlogon.exe e que tem a função de fazer a interface com o usuário para realizar o logon na estação. A MsGina.dll é a GINA original do sistema, mas podemos construir nossa própria GINA a fim de proporcionar maneiras alternativas de autenticação. Um exemplo prático disso é o produto Finger True vendido pela Scua. Este produto altera a GINA do sistema para que, com ajuda de um sensor biométrico, seja exigida a impressão digital do usuário na hora de fazer o Logon no sistema. Depurar uma GINA requer alguns passos atípicos, já que para testá-la é necessário fazer Logon, Logoff e coisas assim. Também é possível depurá-la utilizando o Debug Remoto do Visual Studio, mas na época, depurar a GINA foi a necessidade que tive para aprender a utilizar o SoftICE.

Na Scua haviam duas equipes de desenvolvimento, uma de drivers de Kernel e outra de aplicações. Eu ainda trabalhava na equipe de aplicações, quando em uma reunião de área, a equipe de Kernel me apresentou o SoftICE como uma alternativa para resolver os problemas de Debug que eu estava enfrentando. Eu estava utilizando técnicas como arquivos de Log e MessageBox para depurar a GINA. Vocês podem imaginar os MessageBox com as típicas mensagens de “Passei na rotina X”, “Retornando da rotina Y”. Depois que aprendi a utilizar o SoftICE, ele passou a resolver muitas coisas para mim. Mesmo porque, outras GINAS tinham que ser desenvolvidas, e com o tempo, passei a desenvolver drivers de Kernel.

A maior parte da equipe de aplicações tinha um certo pânico de usar o SoftICE. Uma situação bem semelhante à descrita em meu post anterior. Eles diziam: “Ah não, usar o SoftICE é muito complicado. Vou continuar com os MessageBox. Caso eu não consiga, então utilizarei o esse Debugger de Kernel”. Acho que foi só uma questão de costume, o SoftICE não é nenhum bicho de sete cabeças e nem difícil de utilizar. Eu achava engraçado quando uma parte da equipe ficava travada tentando resolver um determinado problema, aquele tipo de bug estranho que ninguém conseguia achar. Eu passava por perto e perguntava: “Porque vocês não usam logo o SoftICE?”, “Não não, acho que não é para tanto.”, diziam eles. Uma hora eu também era chamado para ajudar a descobrir o problema, e na maioria das vezes, em meia hora de Debug eu pegava o problema que eles já perseguiam à dias. Não estou dizendo que sou o super gênio do Debug, ou que eles fossem técnicamente incapazes. Estou dizendo que foi só uma questão de utilizar ferramenta certa. Você poderia cavar um túnel com uma colher de cozinha, mas com uma pá as coisas ficariam bem mais fáceis.

O SoftICE faz parte de um pacote de desenvolvimento chamado Driver Studio que era vendido pela Compuware. Para quem ainda não sabe, a Compuware descontinuou o SoftICE e não podemos contar com uma versão desta ferramenta para o Windows Vista. Com o SoftICE é possível fazer Debug de Kernel utilizando apenas uma máquina, mas o produto ainda possui recursos de Debug remoto através de portas seriais ou ainda placas de rede. Desta forma, também são adotados os nomes Host para a máquina onde se faz o Debug e Target para a máquina que sofre o Debug (Similar ao WinDbg). Aqui adotaremos o nome Host para identificar a máquina onde temos o compilador e a instalação tipo Host do SoftICE. Não estaremos fazendo Debug remoto neste post.

Muito resumidamente, podemos dizer que o SoftICE trabalha da seguinte maneira. Na máquina Host deverá ser gerado um arquivo de símbolos, conhecido como NMS. Este arquivo é copiado juntamente com o driver a ser testado para a máquina Target. Nela, carregamos os símbolos e depuramos o driver. Vamos descrever estes passos com mais detalhes a seguir.

Instalando na máquina Host

Instalar o SoftICE na máquina de desenvolvimento é necessário para que possamos gerar o arquivo NMS. Não se preocupe, você não vai testar seu driver em sua máquina de desenvolvimento. Pelo menos não em seu juízo perfeito. Durante a instalação, você passará pelas típicas telas de setup até chegar na tela exibida acima, onde selecionamos o tipo de instalação desejado. Como vamos utilizar apenas a parte Host da instalação, selecione essa opção e passe para a tela seguinte. Selecione somente a opção “SoftICE Host Components”, de modo que fique como exibida na tela abaixo. O restante desta instalação é next, next…

Instalando na máquina Target

Utilizaremos a máquina de teste de forma que não seja necessário haver duas máquinas para fazer o Debug, e assim, exploraremos este recurso que é normalmente utilizado em campo. Para isso selecione a opção “Full Instalation” na primeira tela. Em seguida selecione apenas os ítens “SoftICE Host Components” e “SoftICE Target Components”, de forma que fique como exibido abaixo.

Neste caso, ao final da cópia e registro dos arquivos, teremos que configurar algumas propriedades do depurador. O primeiro grupo de configurações se refere à inicialização. Vamos selecionar a inicialização manual neste primeiro momento. Todas estas configurações podem ser alteradas depois que o produto foi instalado. A tela de configuração deve ficar como exibida abaixo.

O próximo grupo será o de configurações gerais. Neste item vamos mudar o campo “Initialization” para que fique com a configuração como exibida abaixo. Estes são comandos que são executados no momento em que o depurador é iniciado. Cada comando é separado por ponto e vírgula. Estes comandos farão as seguintes alterações:

  • LINES 60; Mudar a quantidade total de linhas para 60
  • WC 30; Mudar o tamanho da janela de código para 30 linhas
  • WL 10; Mudar o tamanho da janela de variaveis locais para 10 linhas
  • X; E finalmente o comando que segue com a execução normal do sistema

A falta do comando “X” fará com que o sistema fique paralizado na inicialização do depurador. Isso nos dá a oportunidade de colocar breakpoints inicias e só depois continuariamos com a execução do sistema com a tecla F5, que é a tecla de atalho para o comando “X”.

Agora vamos configurar o vídeo. Neste momento você me pergunta: “Mas como assim configurar o vídeo? O Windows não implementa uma camada de abstração chamada GDI?”

O SoftICE é um depurador de Kernel do sistema. A GDI faz parte do sistema. Como seria depurar um driver de vídeo se o próprio depurador utilizasse tal driver? O depurador deveria influenciar o mínimo possível no sistema depurado. É por esse motivo que o WinDbg precisa de um cabo serial e de outra máquina inteira para tornar o Debug de Kernel possível. Analogamente, o SoftICE, depois de carregado, não pode utilizar nenhum recurso do sistema. Isso inclui drivers de vídeo, disco, teclado, mouse e assim por diante. Para que o SoftICE possa ter um lugar no vídeo enquanto depurando o sistema, ele acessa a memória de vídeo diretamente e desenha “na mão” toda a sua interface. É por isso que temos que configurar o vídeo.

Esta configuração pode ser escolhida entre duas opções principais. A primeira é a “Universal Vídeo Driver”, onde a interface aparecerá em uma “janela”. Esta “janela” na verdade é o resultado da escrita em memória de vídeo que nos dá a impressão de ser uma janela. Este não é o tipo de janela que estamos acostumados a ver e arrastar com o mouse ou mesmo sofrer a ação do ALT+TAB. Lembre-se, quando o SoftICE exibe sua interface, todo o sistema está congelado. A outra opção é a de tela cheia, onde o SoftICE alterna o modo do vídeo para modo texto para exibir sua interface.

Se você estiver instalando o SoftICE em uma máquina virtual, alguns passos são necessários:

  • Não instalar ferramentas de aceleração de vídeo tais como VmTools.
  • Utilizar o driver padrão VGA do Windows e configurá-lo para que fique em 640×480 com 16 cores. (nojento mas necessário)
  • Selecionar a opção de “Tela cheia” no SoftICE.

Se estes passos não forem seguidos, a máquina ficará congelada quando solicitado, mas a tela do depurador não aparecerá. Admitindo que estamos instalando em uma máquina real, selecione a opção de vídeo como aparece abaixo.

O restante é next, next…

Gerando o arquivo NMS

Na máquina Host, depois de escrever e compilar o seu driver (se você ainda não fez isso leia este outro post), agora você deve rodar a aplicação “SoftICE Symbol Loader” que foi instalada. Esta aplicação faz a tradução dos símbolos e gera o arquivo NMS. Selecione a opção Open… do menu File e aponte o driver que você vai depurar. Depois de aberto, o programa deve colocar o nome do driver carregado no título da janela. Eu numerei os três botões que precisaremos para esta operação.

  • Certifique-se que o botão 2 esteja pressionado. Isso vai fazer com que todo o código fonte do driver seja anexado ao arquivo NMS resultante.
  • Certifique-se também de que o botão 3 esteja liberado. Isso vai evitar que o programa fique solicitando por fontes que ele não encontrar.
  • Clique no botão 1 que fará a tradução dos simbolos e irá gerar o arquivo de extensão NMS no diretório local.

Iniciando o SoftICE

Depois de instalar seu driver normalmente na máquina Target, estaremos prontos para iniciar o Debug do nosso driver. Lembrando que tanto nosso driver de exemplo quanto o SoftICE estão configurados com Start manual. Para iniciar o SoftICE você pode clicar no ícone “Start SoftICE” que foi instalado no seu menu Iniciar ou simplesmente executar o comando “net start ntice” na janela “Run…” do Windows. Para se certificar de que o depurador foi carregado, pressione as teclas CTRL+D para que o sistema congele e seja apresentada a tela abaixo.

Não, isso não é um CRASH DUMP da sua placa de vídeo que acabou de explodir. Senhores, é com prazer que vos apresento o SoftICE. Agora você entende o pânico da turma de aplicações? Não se preocupe, ele é feio mas não morde. Pressionando F5 o sistema volta a execução normal.

Agora teremos que carregar o arquivo NMS no depurador. Isso é feito facilmente simplesmente dando um duplo clique sobre o arquivo de extensão NMS. Este arquivo pode estar em qualquer diretório da máquina. O único momento em que este arquivo é utilizado é quando você o carrega no depurador. Para verificar se o arquivo foi carregado pelo SoftICE, utilizamos o comando “table”, que lista todas as tabelas de símbolos carregadas. Várias tabelas podem ser carregadas simultaneamente, mas somente uma fica ativa por vez. O comando “file *” lista todos os arquivos de uma determinada tabela. Para abrir um arquivo em específico, coloque o nome do arquivo na frente do comando. Veja no exemplo abaixo.

Com o arquivo já aberto na janela de código, pressione ALT+C para que o cursor vá para o código fonte. Se esta seqüência de teclas não estiver funcionando, pressione ESC e em seguida ALT+C. Repare que você só consegue caminhar com o cursor para cima e para baixo. As tentativas de mover o curor para os lados faz com que a janela de comandos ganhe o foco novamente. Coloque o cursor sobre a linha que você deseja inserir o breakpoint e pressione F9. Neste momento a linha deveria ganhar destaque como mostra a imagem abaixo.

Agora vamos pressionar F5 para que o sistema volte ao funcionamento normal. No momento em que o driver for iniciado, nosso breakpoint irá interromper esta ação e exibir a interface do SoftICE. A linha em destaque mostra qual será a próxima instução a ser executada. Pressionando as teclas ALT+L, a janela de variáveis locais ganha foco. Você pode navegar entre as variáveis movendo o cursor para cima e para baixo. Pressione a tecla ENTER sobre as estruturas que começam com “+” para que a estrutura seja expandida. A imagem abaixo mostra a janela de registradores seguida da janela de variáveis locais.

Vou deixar uma pequena tabela de comandos aqui, mas a referência completa está no PDF “SoftICE Command Reference”.

  • F5 : Run
  • F9 : Breakpoint
  • F8 : Step into
  • F10 : Step over
  • F12 : Step out
  • F7 : Run to cursor
  • WL : Janela de variáveis locais
  • WW : Janela de Watch
  • WD : Janela de memória
  • F3 : Alterna entre fonte C/Assembly/Mixed

É óbvio que existem inúmeros detalhes e técnicas de utilização, mas vamos deixar isso para os manuais que vêm com o produto.

Nossa, que post longo! Pensou que ia ser fácil não é? Até a próxima…

Step into Kernel (Serial)

1 de December de 2006

Ganhei meu primeiro computador aos 13 anos de idade, mas foi só depois de 7 anos, quando comecei meu estágio, que descobri que era possível depurar os programas que eu escrevia. Até lá, meus métodos de depuração sempre foram coisas como imprimir o valor da variável na tela. Tudo bem que nesse tempo eu não desenvolvia programas complexos o suficiente para ficar sem saída, e com o passar do tempo, acho que me acostumei a trabalhar sem esse luxo todo de breakpoint e tal.

Quando fui apresentado a um depurador, nem dei o devido valor para aquilo. Eu pensava comigo mesmo: “É só colocar um printf e beleza. Não preciso de toda essa parafernalha.”. Na época utilizávamos o CodeView, um depurador 16 bits que roda em DOS, que é exibido na tela abaixo.

Não demorou muito para eu começar a depender do depurador para fazer as coisas mais simples, como escovar os dentes por exemplo. Na verdade, algumas situações como escrever código para coletores de dados, escrever firmwares para hardwares que não tinham display, situações nas quais não podíamos contar nem com uma porta serial para saber o que se passava com o software, e a inesquecível situação onde havíamos colocado um ocsiloscópio em um determinado pino do processador para capturar sinais de vida do nosso software, enfim, situações onde daríamos um braço para ter um simples breakpoint me mostraram que o depurador não é perfumaria.

O engraçado é que hoje em dia, na faculdade, a grande maioria dos alunos da minha turma não sabe depurar software. Eu já tentei explicar para meus amigos o tamanho da vantagem de utilizar um depurador, mas eles acabam tendo a mesma reação que tive anos atrás: “Ah não Fernando, isso é muito complicado. Só de olhar a gente acaba encontrando o erro.”. Por mim tudo bem…

Bom, a gente está aqui pra beber ou pra conversar? Vamos depurar o driver gerado pelo tradicional post Getting Started. Desta vez, vamos fazer como manda a tradição. Vamos precisar de duas máquinas, um cabo serial do tipo Null Modem e por último e não menos importante, uma cópia do Windbg. Não, não adianta ler esta frase de novo, você não entendeu errado, você vai precisar realmente de duas máquinas. Não sei porque, algumas pessoas apresentam uma certa resistência em acreditar nisso. Bom, suponho que superamos essa fase e podemos continuar com o post.

Se você ainda não tem uma cópia do Windbg, você poderá baixa-lo gratuitamente da página do Windows Debugging Tools no site da Microsoft.

Vamos tomar esta imagem ao lado emprestada do help do Windbg, que mostra como devemos ter os micros para realizar o Debug de Kernel.

A máquina nomeada HOST será onde teremos o WinDbg rodando. Esta máquina é, na maioria das vezes, a máquina onde o driver foi desenvolvido. Vamos partir do princípio que esta é a máquina onde o driver foi desenvolvido e adiar os detalhes de como configurar o diretório de símbolos e fontes para um outro post. A máquina nomeada TARGET é onde teremos nosso driver carregado pelo sistema. O sistema operacional da máquina TARGET não precisa necessariamente ser Checked Build, nem é necessário instalar nenhum kit adicional ao sistema operacional. Tudo o que precisamos é do seu driver e de uma porta serial. Todos os Windows da plataforma NT (Windows NT, Windows 2000, Windows XP, Windows 2003 Server e Windows Vista) já trazem seu depurador nativo desde a sua instalação. Na verdade, essa é uma excelente característica no uso do Windbg. Imagine aquele tipo de problema que só se manifesta na máquina do cliente. Você não vai querer instalar nada agressivo ou mesmo que mude o cenário de forma que o problema não se manifeste mais. Acredite, isso não é tão raro assim. Nestes casos, basta habilitar o Debug e pronto.

Para habilitar o Debug na máquina TARGET, precisaremos editar alguns parâmetros de inicialização que estão no arquivo Boot.ini localizado na pasta raiz do sistema. Este arquivo está com os atributos de arquivo de sistema, arquivo oculto e também como somente leitura, talvez seja necessário configurar o Windows Explorer para que seja possível ver estes arquivos. Utilizando o Windows Explorer, vá até a pasta raiz, remova a propriedade de somente leitura do arquivo Boot.ini, em seguia, abra este arquivo utilizando um editor de texto como o Bloco de Notas por exemplo. O conteúdo deste arquivo é semelhante ao demonstrado baixo.

Na sessão Operating Systems você terá que duplicar a linha do sistema que você vai querer depurar. Adicione ao final desta linha os parâmetros /debugport=com1 /baudrate=115200 que irão configurar o modo Debug. O primeiro parâmetro seleciona a porta COM a ser utilizada, enquanto o segundo seleciona a velocidade da comunicação. O protocolo serial não é o meio mais rápido de comunicação entre as máquinas HOST e TARGET, e em algumas situações chega a ser desagradável ter que esperar as interações entre o WinDbg e o sistema depurado. Existem outros meios de comunicação que podem ser utilizados caso seu computador não tenha uma porta serial disponível ou caso você queria ter mais velocidade e conforto no Debug. Veja mais detalhes no post Serial Killers.

O resultado final do nosso arquivo Boot.ini deveria ser algo semelhante ao exibido abaixo. Vou pular o inicio as linhas que decrevem o sistema operacional para a melhor visualização colocando “…”.

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(2)\WINDOWS
[operating systems]
multi(0)... /NoExecute=OptIn
multi(0)... /NoExecute=OptIn /debugport=com1 /baudrate=115200

Feitas estas alterações, você pode salvar o arquivo e restaurar os atributos originais do arquivo. No Windows XP e Windows 2003, os mesmos passos acima descritos poderiam ser feitos com a ajuda de uma ferramenta chamada Bootcfg.exe. A partir do Windows Vista este processo é bem diferente e vou descreve-los em um post futuro.

De volta à máquina HOST, inicie o WinDbg e selecione a opção Kernel Debug… do menu File. Deverá ser exibida uma janela que configura o meio de comunicação. Faça isso de forma que fique compatível com o que foi configurado no arquivo Boot.ini da máquina TARGET. Neste caso, estamos utilizando a porta serial COM1 e baud rate de 115200. Clicando em OK o WinDbg vai abrir a porta serial da máquina HOST e vai esperar até que a máquina TARGET esteja pronta. Neste ponto, teremos a seguinte mensagem na janela de comandos do WinDbg.

Enquanto a máquina HOST aguarda, certifique-se de que seu driver está instalado na máquina TARGET e a reinicie. Depois de reiniciada, quando sistema for iniciar a sua carga, o Loader do sistema irá exibir as opções encontradas no arquivo Boot.ini editadas por você. Selecione a opção onde aparece [debugger enabled] como mostra abaixo.

Selecionada esta opção, as máquinas HOST e TARGET deveriam se conectar e na janela Command seria exibiria uma saíba semelhante à mostrada abaixo.

Microsoft (R) Windows Debugger  Version 6.6.0007.5
Copyright (c) Microsoft Corporation. All rights reserved.
 
Opened \\.\com1
Waiting to reconnect...
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path.           *
* Use .symfix to have the debugger choose a symbol path.                   *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is:
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
*                                                                   *
* The Symbol Path can be set by:                                    *
*   using the _NT_SYMBOL_PATH environment variable.                 *
*   using the -y  argument when starting the debugger. *
*   using .sympath and .sympath+                                    *
*********************************************************************
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for
ntkrnlpa.exe -
Windows XP Kernel Version 2600 UP Free x86 compatible
Built by: 2600.xpsp_sp2_gdr.050301-1519
Kernel base = 0x804d7000 PsLoadedModuleList = 0x805531a0
 

Muito bem, até aqui sabemos que as máquinas estão conectadas. Pressionando as teclas Ctrl + Break no Windbg, faremos com que o sistema fique congelado na máquina TARGET e que o controle seja passado ao depurador. O depurador estará pronto para receber seus comandos quando aparecer um prompt de comandos indicado pelas letras KD no canto inferior esquerdo da janela Command.

Apenas para fazer um simples teste, digite o comando “lm” e tecle enter. Este comando lista os módulos carregados pelo sistema. Note que o driver Useless ainda não está nesta lista. Isso acontece porque o driver exemplo está configurado para ter sua execução iniciada manualmente, desta forma, o driver ainda não foi carregado pelo sistema. Em seguida, selecione o ítem Open Source File… do menu File e abra o arquivo Useless.c. Clique sobre o nome da função DriverEntry e pressione F9. Embora não haja nenhum sinal visível disso, colocamos um breakpoint nesta função. O fato de não ter nenhuma alteração visual se deve ao fato de que nosso módulo ainda não está carregado. Podemos nos certificar de que o breakpoint está instalado listando os breakpoints com o comando “bl”.

kd> bl
 0 e f9fb3430     0001 (0001) Useless!DriverEntry

Agora vamos lançar o comando “g” que fará com que o sistema volte a execução normal.

Depois que o sistema for carregado, vamos iniciar o driver através do comando net start Useless. Quando o driver for iniciado, o entry point DriverEntry será executado e por conseqüência teremos a execução interrompida pelo nosso breakpoint. A máquina TARGET ficará congelada enquanto o depurador detém o controle sobre o sistema. Repare que agora que nosso módulo está carregado, os breakpoints são facilmente identificados pelas linhas com a cor de fundo vermelha.

Bom, os primeiros passos já foram dados, os comandos e detalhes de como depurar o Kernel de Windows estariam fora do escopo deste post. Mas uma boa dica de como obter kilos de detalhes sobre este assunto é o livro Windows 2000 Kernel Debugging. O livro não é um dos meus preferidos, ele dá uma boa introdução ao assunto além de falar sobre como utilizar e construir Debug Extensions, mas não chega a ter as técnicas ninjas utilizadas pelos verdadeiros mestres do Kernel Debugging. Uma outra excelente fonte de detalhes sobre este assunto é a lista de discussão Windows Debugger Users List dedicada ao Windbg. Isso tudo sem nos esquecermos do Help.

Este foi um post inicial sobre o assunto, aguardem por posts futuros onde darei os passos de como utilizar o Windbg com a VMware e de como depurar o Kernel do Windows com apenas uma máquina utilizando o SoftIce (que Deus o tenha).

Have fun… 😉

Serial Killers

24 de October de 2006

Não há mais dúvidas, estão mesmo acabando com as portas seriais em notebooks e desktops. Neste post vou falar sobre alguns problemas que encontramos quando é necessário depurar aquele driver que só dá problema naquela máquina que não tem portas seriais. Quais as alternativas que temos em relação a isso?

Este mês chegaram micros novos aqui na empresa. Nestas máquinas, colocamos algumas versões beta de nossos produtos. Por algum motivo, somente nas máquinas novas, um dos nossos drivers não estava funcionando como deveria. Conforme o cita o código de ética do programador, a culpa é do estagiário que fazia os testes até que se prove o contrário. Depois de algumas tentativas frustradas de descobrir o que estava acontecendo, não tive dúvidas, vamos depurar. Para não ter que deslocar a vítima até minha mesa para conectar o cabo serial, resolvi instalar o SoftIce. Mas a vida é uma caixinha de surpresas e obtivemos uma bela BSOD quando iniciamos o SoftIce. Wow!!! Isso é raro, mas acontece. Nestes casos não temos muita escolha, vamos ter que utilizar o Windbg mesmo. Os micros que chegaram são do modelo Dimension 5150 da Dell. Dê uma olhada na parte traseira do gabinete na foto ao lado e responda rapidamente: Onde está a porta serial? Pois é, não tem mesmo. Consultando o site do fabricante, verificamos que o micro dispõe de 8 portas USB, mas nada de porta paralela e nada de porta serial.

Neste momento, fizemos uma roda e falamos todos juntos: “Oh Deus, o que faremos agora?”. Alguns dos problemas que acontecem em máquinas reais são reproduzidos em máquinas virtuais, principalmente se o driver que você está desenvolvendo é um filtro ou um driver que não lide diretamente com o hardware. Para fazer um teste, instalamos a VMware em uma das máquinas novas e felizmente o problema foi reproduzido. Essa é uma daquelas ocasiões onde ficamos felizes pelo problema aparecer. Daí em diante, foi só utilizar o velho truque da porta serial virtual na máquina virtual e redirecionar os dados para um named pipe. Isso até poderia virar um post.;-)

Bom, com o debugger conectado, break-point setado, não precisou de muito tempo para encontrar o problema, gerar uma nova versão, testar, funcionar e viver feliz para sempre. Mas nem sempre a história se resolve com estes poucos passos. Algumas máquinas virtuais não dão suporte a dispositivos USB. Mesmo a VMware que oferece este recurso, ainda não dá suporte a dispositivos de interface humana (HID) como teclados e mouses USB. Isso sem falar dos problemas psico-esotéricos que envolvem race conditions e/ou uma boa ação conjunta com Murphy. O que podemos fazer nestes casos além de sentar e chorar?

Felizmente a tecnologia a serviço da humanidade previu situações como estas. Nestes casos temos tradicionalmente duas alternativas:

1) Descrever o bug que você quer eliminar em uma folha de papel. É recomendado que esta descrição tenha trechos como “Sai bug estranho sai…”. Costurar a folha de papel dentro da boca de um sapo e com o pensamento positivo na resolução do problema, atire o sapo em um rio sem que você veja onde ele caiu. Depois de sete dias, dê um “Rebuild All” em seu projeto (Um reboot antes do build é recomendado). Caso o problema persista, repita a operação. Formatar a máquina ajuda a eliminar os maus fluídos e a espantar os espíritos atormentados que assombram o seu código. Consulte uma benzedeira de software para obter melhores resultados.

2) Utilizar uma placa FireWire e fazer a conexão do Windbg utilizando um cabo IEEE 1394. Esta opção só estará disponível se a máquina a ser depurada for um Windows XP ou superior. Estas placas são espetadas em seu barramento PCI ou ainda PCMCIA. Ainda não cheguei a utilizar este tipo de conexão para depurar uma máquina, mas é seguramente bem rápido e confortável sabendo que os dados são transmitidos a uma taxa de até 400Mbps.

Não posso utilizar um daqueles famosos conversores USB para portas seriais que são vendidos na Santa Ifigênia? Mesmo que não seja necessário instalar um driver no seu sistema, estes adaptadores utilizam drivers para funcionar. Toda a pilha USB é montada para que estes dispositivos funcionem. Em uma máquina que está sendo depurada em Kernel, todo o código que trata a comunicação serial ou firewire está hard coded no loader do sistema e trabalha com endereços fixos padrões. Estes adaptadores podem ser utilizados sem problemas pela máquina que fará o Debug, mas não pelas que irão sofrer o Debug.

E se eu utilizar uma placa multi-serial PCI ? Isso vai depender de quais endereços de I/O e interrupções a placa vai oferecer. Normalmente estas placas utilizam endereços diferentes dos endereços padrões a fim de não criar nenhuma incompatibilidade com as portas que possivelmente pré-existam na máquina. Mas se a placa oferecer a opção de utilizar os endereços padrões, não haverá problemas.

O Windows Vista trará suporte a Debug de Kernel via porta USB 2.0, entretanto algumas condições serão exigidas. O cabo USB deverá ser especial para este fim, a interface USB do computador sendo depurado deverá oferecer suporte a Debug de Kernel, e por último e não menos importante, a controladora USB do computador que fará o Debug deverá ser compatível com Extended Host Controller Interface(EHCI).

Caso você se interesse em adquirir interfaces IEEE 1394, lembre-se que você deverá ter pelo menos duas interfaces deste tipo para que haja o link entre a máquina depuradora e a máquina depurada. Embora eu tenha visto alguns comentários perdidos na Internet sobre cabos conversores USB x FireWire (para utilizar na máquina depuradora), até onde pude ver são eletricamente impossíveis de serem construídos. Isso porque todo o protocolo é diferente. Enquanto o USB é um protocolo “Master x Slave”, o FireWire é “Peer to Peer”. Seria necessário algum hardware inteligente no meio do caminho para fazer toda a tradução.

Estamos adquirindo estas interfaces FireWire para PCMCIA aqui na Open a fim de eliminar o problema de depurar notebooks de clientes que nasceram aleijados de portas seriais. Creio que em pouco tempo poderemos abrir mão do sapo e tudo mais. Farei algumas comparações com o bom e velho cabo serial e darei alguma notícia sobre este assunto.