Depuração 'printf' Melhorada

Outras línguas: English Español 한국어 中文

Uma das técnicas de depuração mais comuns, a depuração ‘printf’ é particularmente popular porque a maioria das pessoas a aprende intuitivamente quando escreve os seus primeiros programas.

A depuração ‘printf’ é muito acessível porque você não precisa de nenhuma ferramenta especial para ela. Ao lidar com os seus primeiros bugs, mesmo antes de saber o que é um depurador, ela naturalmente vem à mente para fazer o seu programa imprimir variáveis passo a passo, para que você possa seguir a execução no console.

Apesar de ser uma das técnicas de depuração mais básicas, desenvolvedores experientes também a usam muito. Ela pode-te ajudar a investigar qualquer tipo de problema, como rotinas subótimas, estado inconsistente, problemas de multithreading, e mais.

Como eu já mencionei, esta técnica não requer que você use nenhuma ferramenta especial, como uma IDE. No entanto, se você estiver a usar uma, ela pode torná-lo ainda mais eficiente em fazer o registro do estado do programa.

Info icon

Este artigo mostra recursos do IntelliJ IDEA. Recursos semelhantes podem ou não estar disponíveis em outras IDEs. Se você está usando uma ferramenta diferente, considere verificar a documentação dela para ver se esses recursos também estão presentes lá.

Live templates

O IntelliJ IDEA fornece live templates para os padrões de registro de depuração mais comum. Para usar um modelo ao vivo para registro de depuração, digite o comando correspondente e pressione Tab. O IntelliJ IDEA irá gerar a declaração de impressão e inseri-la no cursor.

Vejamos alguns exemplos.

Registrar parâmetros do método


public static BufferedImage recolor(BufferedImage in, BufferedImage mask, int newColor) {

    // digite 'soutp' aqui, depois pressione Tab

    return null;
}
public static BufferedImage recolor(BufferedImage in, BufferedImage mask, int newColor) {

    System.out.println("in = " + in + ", mask = " + mask + ", newColor = " + newColor);

    return null;
}

Registrar valores


public static double coolMethod(double parameter) {
    double a = Math.random();
    double b = Math.random();

    // digite 'soutv' aqui, pressione Tab e então selecione o valor

    return a * b * parameter;
}
public static double coolMethod(double parameter) {
    double a = Math.random();
    double b = Math.random();

    System.out.println("b = " + b);

    return a * b * parameter;
}

Registrar entradas de método


public static BufferedImage recolor(BufferedImage in, BufferedImage mask, int newColor) {

    // digite 'soutm' aqui

    return null;
}
public static BufferedImage recolor(BufferedImage in, BufferedImage mask, int newColor) {

    System.out.println("ImageUtils.recolor");

    return null;
}

Pontos de interrupção de registro

Uma das desvantagens da depuração com declarações de impressão é que elas introduzem a sobrecarga de gerenciamento manual. Você não pode ligá-las e desligá-las rapidamente, e definitivamente não quer se comprometer acidentalmente e executá-las em produção.

Por essa razão, se você precisa registrar algo para fins de depuração, eu recomendaria o uso de pontos de interrupção de registro, já que eles são muito mais fáceis de gerenciar.

Ponto de interrupção de registro mostrado como um círculo amarelo na guia do editor Ponto de interrupção de registro mostrado como um círculo amarelo na guia do editor

Para definir um ponto de interrupção de registro, mantenha pressionado Shift, depois clique na guia. Ao contrário de um ponto de interrupção regular, ele não suspende a execução do programa, mas imprime no console em vez disso.

Por padrão, é uma mensagem indicando que o programa chegou a esta linha. Você também pode usar as opções próximas à caixa de seleção Evaluate and log nas configurações do ponto de interrupção se preferir registrar o rastreamento de pilha atual ou o resultado de uma expressão personalizada.

Diálogo de configurações de ponto de interrupção com uma expressão personalizada no campo 'Evaluate and log', e caixa de seleção 'Suspend' desmarcada Diálogo de configurações de ponto de interrupção com uma expressão personalizada no campo 'Evaluate and log', e caixa de seleção 'Suspend' desmarcada
Info icon

Tenha cuidado com expressões de registro. Avaliar aquelas que causam efeitos colaterais pode ser uma fonte de novos bugs ou comportamentos inesperados. Além disso, quando usados em código quente, eles podem retardar significativamente o seu programa.

Quando os pontos de interrupção de registro tornam-se numerosos, você pode acompanhar e gerenciá-los no diálogo Breakpoints (Run | View Breakpoints):

O diálogo 'Breakpoints' mostra todos os pontos de interrupção dentro do projeto agrupados por tipo O diálogo 'Breakpoints' mostra todos os pontos de interrupção dentro do projeto agrupados por tipo

Você pode até criar grupos personalizados para eles:

Clicando com o botão direito do mouse em um ponto de interrupção no diálogo 'Breakpoints' mostra um menu de contexto com a opção 'Move to group' Clicando com o botão direito do mouse em um ponto de interrupção no diálogo 'Breakpoints' mostra um menu de contexto com a opção 'Move to group'

Isso te ajudará a gerir os seus pontos de interrupção de uma maneira centralizada. Por exemplo, você pode criar um grupo relacionado a um bug específico e salvá-lo para mais tarde. Quando o problema for resolvido, desative o grupo. Dessa forma, se o problema reaparecer, não será necessário recriar tudo do zero. Você simplesmente reativa o grupo novamente.

Registro de eventos frequentes

Para eventos que ocorrem muito durante a execução do programa, registrar cada evento individual pode ser superfaturado. Isso não só inunda o console com mensagens, mas muita interação com I/O pode retardar significativamente a sessão de depuração.

Console com muitas mensagens similares, como 'Mouse moved to 380, 183' Console com muitas mensagens similares, como 'Mouse moved to 380, 183'

Para tais eventos, pode ser útil usar o recurso Pass count. Você pode acessá-lo no diálogo Breakpoints.

Diálogo de configurações de ponto de interrupção com o campo 'Pass count' definido para 100 Diálogo de configurações de ponto de interrupção com o campo 'Pass count' definido para 100

Após ter definido Pass count para um valor específico, o ponto de interrupção correspondente só será acionado a cada n-ésimo acerto, garantindo que o registro não se torne uma perturbação.

Summary

Independentemente de você estar a inserir declarações de impressão ou definindo pontos de interrupção de registro para depuração, as ferramentas modernas têm recursos para melhorar a sua experiência de depuração. Com este post, eu queria ter certeza de que você está ciente desses pequenos truques que tornam todo o processo mais prazeroso.

Feliz depuração!

all posts ->