DEPURAÇÃO DESVENDADA Apresentarei para vocês um assunto de extrema importância no desenvolvimento de sistemas de qualquer tipo - a depuração. Depurar um aplicativo é tão fundamental que a maioria dos gerentes de projeto incluem os testes e a depuração de sistemas como uma fase do ciclo de vida de um software. Veja uma visão detalhada dos principais recursos do depurador do Delphi. O que é e por que depurar? O termo "depurar" é uma tradução livre do inglês debug ("remover bugs").quem nunca ouviu ou usou a frase "Meu sìstema está com bug"? Neste caso, o bug é uma falha do sistema, um erro, um cálculo mal feito, operações com resultados incorretos, e assim por diante. É neste ponto que entra o Debugger (Depurador) - para localizar e eliminar bugs dos códigos. Além de simplificar a localização de erros, o depurador pode prevenir que futuros erros venham a acontecer, simulando situações pelas quais seu usuário final passaria. Você pode ainda utilizálo para simplificar e otimizar seus sistemas. Um software bem depurado é um software mais confiável, com menos probabilidade de erros, mais rápido e seguro, e certamente trará mais satisfação para você e seu cliente. O depurador integrado do Delphi Desde os tempos do Turbo Pascal - precursor do Delphi - o depurador já era uma ferramenta extremamente poderosa. O Delphi trabalha exatamente da mesma forma que o Pascal, com uso de breakpoints, watches etc. e introduz muitos outros recursos. Se você sabia depurar em Pascal, pode facilmente depurar no Delphì. Tanto o Turbo Pascal como o Delphì sempre tiveram o depurador integrado à IDE. Não é necessário que você saia do Delphi e abra outro software exclusivamente para depurar o executável, obrigando a usar endereços de memória e comandos especiais de depuração. O Delphi nos dá uma visão completa de tudo o que está acontecendo dentro do processo executável ou DLL podemos inspecionar variáveis, fluxos de mensagens, executar código passo a passo, examinar threads e mais, tudo dentro da própria IDE. Paradas com breakpoints Quem nunca colocou uma mensagem "Olá, passei por aqui" para saber se determinada linha de código estava sendo executada? Ou ainda, quem nunca mostrou o valor de uma variável numa janela para verificar seu valor atual? Alguns chamam estes artifícios de "depurador dos pobres. O depurador do Delphi oferece ferramentas bem mais poderosas para isso. Certamente o recurso mais simples é o uso de breakpoints, ou pontos de interrupção. Você pode definir um breakpoint no código fonte de sua aplicação com isso, a execução do programa é suspensa quando a linha de código marcada
estiver pronta para ser executada. Isso nos permite monitorar detalhadamente o fluxo de execução do código, examinando valores de variáveis e chamadas de rotinas. Como exemplo, adicionei um botão e um Edit (todos da palheta Standard) em um novo formulário e, no evento OnClick coloquei o seguinte código, que monta uma string de 10 letras escolhidas aleatoriamente, como por exemplo 'ABCDEFGHIJ' e as exibirá no Edit1: Não se esqueça de dar um clique duplo para inserir o código no Botão! procedure TForm1.Button1Click(Sender: TObject); var Loop: Integer; Str: String; Randomize; for loop:=1 to 10 do // adiciona uma letra de A a Z em Str Str:= Str + Chr(Random(26) + 65); Edit1.Text:= Str; Imagine agora que quiséssemos observar a execução deste código a cada iteração do loop for. Poderíamos criar um breakpoint, clicando do lado esquerdo da linha de código onde queremos que a execução seja interrompida. Isto adiciona um ícone à esquerda da linha e marca-a em vermelho (cor padrão). Ao executar a aplicação e clicar no botão, o depurador interrompe a execução do programa e indica a linha onde parou com uma seta verde. Um detalhe: observe que após compilar a aplicação, o depurador indica - com pequenas marcas azuis - quais linhas foram usadas para montar o código compilado final. Algumas linhas não possuem estas marcas, significando que foram removidas do código final na otimização feita pelo compilador. Você não pode marcar breakpoints nestas linhas. Grandes passos com Step Over Vamos executar a operação passo a passo, para observar o fluxo de execução do loop. Escolha "Run Step Over, ou simplesmente pressione F8. O depurador passa para a próxima linha compilada, destacando-a. Veja a figura abaixo.
Em seguida você pode pressionar a tecla F8 mais algumas vezes e observar a montagem da variável "Str" Para continuar a execução do programa ou passar para o próximo breakpoint (se houver), pressione F9. Valores com hints Para saber o valor atual de "Str", basta repousar o mouse sobre qualquer parte do código que contenha uma referência à variável - o valor é mostrado em um hint. Este recurso é conhecido no Delphi ou em qualquer outra linguagem como Tooltip Symbol Insight. Você pode usar este recurso para observar não somente o valor de uma variável simples, mas também valores de campos TField, instruções SQL, propriedades de componentes visuais e mais. Pequenos passos com Trace Into Vamos examinar o comando de depuração "Trace Into: Modifique nosso código, colocando a atribuição da variável Str em uma procedure separada: procedure MontarStr(var Str: string); Str := Str + chr(random(26) + 65); MontarStr(Str); Substitua a linha de atribuição de Str por:
O código fonte completo deverá estar assim então: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(tform) Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } var Form1: TForm1; implementation procedure MontarStr(var Str: string); Str := Str + chr(random(26) + 65); {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var loop: integer; Str: string; randomize; for loop := 1 to 10 do MontarStr(Str); Edit1.Text := Str; end. Deixe o breakpoint sobre MontarStr abaixo do for e execute a aplicação. Pressione o botão para observar o fluxo do código. Se você executar passo a passo com F8, notará que, quando passamos por MantarStr, o depurador não entra no corpo da procedure. Para que isso aconteça, quando a linha de execução estiver sobre MontarStr, pressione F7 (ou use "Run Trace Into"). Isso faz com que o depurador entre no código da rotina. Até o retorno Em um grande sistema com muitas rotinas (procedures e funções), você vai querer que o depurador entre em alguns trechos de código e outros não. Se você acidentalmente pressionar
F7 ao invés de F8, e entrar em uma rotina, não precisará pressionar F8 até chegar ao seu final. Você pode retornar a execução ao ponto de chamada da rotina, usando o comando "Run Run Until Return", ou pressionando SHIFT+F8. Monitoração de variáveis Outro recurso do depurador é a "Watch Lìst, uma janela especial utilizada para a exibição de valores de variáveis. Para visualizá-la, clique em "View Debug Wíndows > Watches". O Watch List é uma lista em que constam variáveis definidas pelo programador que terão o seu conteúdo exibido durante a execução do sistema. Cada variável inserida nessa lista é denominada Watch, daí o nome Watch List. A inserção de um Watch faz-se da seguinte forma: Vá ao menu Run e escolha a opção Add Watch... e será apresentada a seguinte caixa de diálogo: Na caixa Expression digite o nome da variável, constante, matriz, etc., que terá o seu conteúdo sendo exibido ao programador durante a execução do sistema. No nosso caso, a variável será a Str. É importante saber que a execução do programa deverá ser feita em modo linha-a-linha, ou seja, utilizando-se o Trace Into - F7. Definidos os Watch's, veja como ficará a sua Watch List. A mensagem process not accessible indica que o Watch especificado ainda não foi processado por nenhuma instrução. Na figura seguinte poderemos visualizar um exemplo no qual o Watch foi processado:
Você pode depois dar um clique com o botão direito sobre a janela e escolher a opção "Add Watch" para adicionar a variável, componente ou objeto a ser monitorado. Outra dica é dar um clique sobre a janela acima e escolher a opção Stay On Top para que a mesma esteja sempre sendo exibida. Como se pode ver usando o exemplo anterior, adicionei a variável Str à janela "Watch List': Com o breakpoint ativado e executando a aplicação passo a passo, podemos observar os valores de Str durante toda sua vida útil dentro do escopo da procedure Variáveis locais Outra janela do depurador é a janela "Local Variables, que você pode usar para visualizar os valores de todas as variáveis locais à procedure/função que está sendo depurada, o que é muito útil para rotinas com muitas variáveis. Clique em "View Debug Windows > Local Variables". A figura abaixo mostra as variáveis do evento OnClick do botão que está no projeto: Os parâmetros Sender (que neste caso é Button1) e Self (o Form1) não estão acessíveis ao depurador neste ponto do códìgo devido a otimizaçóes do compilador. Evaluate/Modify Você pode simular situações durante a execução através da alteração manual de valores de variáveis, propriedades, objetos etc. No exemplo anterior, adicionei uma string ao final de Str para observar seu comportamento durante a execução. Para modificar o valor de uma variável, durante a depuração, clique com o botão direito sobre o código que referencia a variável e escolha "Debug > Evaluate/ Modify"; depois entre com o novo valor em "New value :
Conclusão: A depuração é essencial para a construção de softwares mais confiáveis, com mais qualidade e com minimização de erros. Isso torna a programação mais robusta e menos sujeita à falhas. O Delphi oferece excelentes opções de depuração de código integradas, que podemos utilizar para monitorar todo o funcionamento, armazenamento de dados e fluxo de execução de nossas aplicações.