1120 Alameda Orquidea, Atibaia, SP,  BRA

fernando@driverentry.com.br

Debug or Not Debug

Aqui está uma coisa muito simples de se fazer. Gerar compilação condicional utilizando o pre-processador juntamente com o símbolo DBG tem que ser uma tarefa simples. Assim como o símbolo _DEBUG é definido pelos projetos escritos em C/C++ no Visual Studio, o símbolo DBG é definido pelo DDK para informar que o build corrente está em Checked ou Free. Assim podemos exemplificar com um trecho muito simples de código como segue abaixo:

//-f--> Tô achando que é fácil...
#ifdef DBG
   DbgPrintf("Versão Checked\n");
#else
   DbgPrintf("Versão Free\n");
#endif

O código acima exibirá a mensagem “Versão Checked” no quando o build for feito em Checked e “Versão Free” quando o build for feito em Free, certo?

ERRADO!!! Isso mesmo, errado! O símbolo DBG é definido como 1 quando em Checked e definido como 0 quando Free. Assim temos DBG=1 quando Checked e DBG=0 quando Free. Da maneira que está, o código acima ainda exibirá a mensagem “Versão Checked” mesmo quando compilado como Free. Isso porque o símbolo DBG ainda é definido, definido como 0, mas é definido. Assim para testar adequadamente esta condição devemos fazê-la com #if no lugar de #ifdef como segue abaixo:

//-f--> Agora sim, exibe a configuração atual do build
#if DBG
   DbgPrintf("Versão Checked\n");
#else
   DbgPrintf("Versão Free\n");
#endif
 
//-f--> Testando apenas o build Free
#if !DBG
   DbgPrintf("Versão Free\n");
#endif

Para facilitar a depuração, não é difícil ver em alguns drivers o código que quando compilado em Checked interrompe a execução utilizando o seguinte código.

//-f--> Breakpoint quando em Checked
#if DBG
   __debugbreak();
#endif

Se o teste do build estivesse incorreto aqui, teríamos um bela tela azul caso o código acima fosse para produção. Como vocês devem saber, a chamada a breakpoints em código lançam exceções que seriam tratadas pelo debugger, mas se o debugger não estiver atachado ao sistema, COISAS HORRIVEIS ACONTECEM.

No arquivo ntddk.h existe a macro abaixo que ajuda a testar condições de build em Checked.

#if DBG
    #define IF_DEBUG if (TRUE)
#else
    #define IF_DEBUG if (FALSE)
#endif

Assim, fica bem clara a sintaxe abaixo:

IF_DEBUG
{
   __debugbreak();
}

Já que estamos falando de builds condicionais, podemos também podem ter especializações de build no arquivo SOURCES. A variável de ambiente DDKBUILDENV é definida como “che” quando o build é feito em Checked, ou definida como “fre” quando em Free. Assim podemos, por exemplo, utilizar paths para libs diferentes de acordo com a configuração do build atual.

!if "$(DDKBUILDENV)" == "fre"
BUILD_CONFIG=Release
!else
BUILD_CONFIG=Debug
!endif
 
TARGETLIBS=.\Lib\$(BUILD_CONFIG)\HtsCpp.lib

4 Responses

Leave a Reply

Your email address will not be published.