murilo ijanc'

Posts | CVS
Mail | PGP

Debug “r00ts”

A verdade é que não consigo deixar de usar o printf(3) bruto véio, posso estar debugando o código fonte do OpenBSD, escrevendo simples programas lá está o fucking printf(3) e que mau tem isso, na verdade nenhum, mas ficar toda hora repetindo printf é zica e como diria meus amigos do interior pode dar zinabre no código lá na frente.

Bom, sinceramente não será agora nesse post que deixarei de usar, nesse caso darei uma aperfeiçoada para ter um pouco mais de controle.

#include <stdio.h>

#if DEBUG
#define debug(fmt, ...) \
        do { fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
         __LINE__, __func__, ##__VA_ARGS__); } while (0)
#else
#define debug(fmt, ...) do {} while(0)
#endif

int
main(int argc, char *argv[])
{
    debug("Isso aparece porque debug está ativado =]\n"); 
    debug("2 + 2 = %d\n", 2 + 2); 

    return (0);
}

Agora, vamos testar:

$ cc debug.c -o sem_debug
$ ./sem_debug # nada vai aparecer
$
$ cc -DDEBUG debug.c -o com_debug
$ ./com_debug
debug.c:14:main(): Isso aparece porque debug está ativado =]
debug.c:15:main(): 2 + 2 = 4

O que usamos acima é o que chamamos de macro variadic, trazendo para um mundo que estamos acostumados são argumentos variáveis da função. Para quem usa python por exemplo existe o *args.

Como observado no exemplo acima além dos argumentos variáveis, existe a mensagem do debug que quero enviar para saída de erro, bem como o nome do arquivo, a linha e o nome da função fica parecendo realmente um logger ultra simplificado.

Obs.: veja que existe dois ## antes de VA_ARGS isso é fundamental caso seja opcional os argumentos passados.

Isso faz com que o debug(“oi”) funcione sem necessitar dos argumentos, caso eu não usasse o token ## eu teria que fazer assim:

...
    debug("%s\n", oi);
...

Bom é isso pessoal =]