Debugando aplicações PHP usando phpdbg - parte 01

O PHP é uma linguagem voltada para a web e vem daí sua força, desde sua criação. Contudo, a depuração de erros pode se tornar uma experiência difícil para os iniciantes na linguagem. O phpdbg é um debugador interativo de linha de comando para explorar e corrigir códigos PHP.

[ Hits: 933 ]

Por: leandro peçanha scardua em 20/07/2022 | Blog: https://leandropecanhascardua.github.io/


Sessão de debugação



O modo básico de iniciar a debugação usando o phpdbg é chamá-lo sem argumentos pela linha de comando:

phpdbg teste.php

[Welcome to phpdbg, the interactive PHP debugger, v7.4.3]
To get help using phpdbg type ?help? and press enter
[Please report bugs to http://bugs.php.net/report.php]
[Successful compilation of /home/leandro/Leandro/linux/teste.php]
prompt>


Isso iniciar um prompt interativo. Para encerrar a sessão de debugação, sair e voltar para a linha de comando do terminal basta digitar quit.

No phpdbg temos três grupos de comandos:
  • Informação: São relacionandos ao código fonte e ao opcode. Servem para consultar qual a linha de código está sendo executada, qual o opcode foi gerado a partir do código fonte e como está sendo executado, além de mostrar o valor de variáveis .
  • Controle de execução: Permite controlar a sessão de debugação, isto é, configurar um ponto de parada, iniciar a execução, voltar a executar o código depois de uma parada, vigiar uma variável ou encerrar a execução entre outras opções.
  • Diversos: Não têm uma característica comum, mas permitem entre outras coisas configurar o ambiente phpdbg, rodar um script phpdbg, rodar um comando no shell entre outras opções.

Digitando help no menu interativo do phpdbg podemos ver a lista completa dos comandos permitidos e digitando help nome do comando podemos ver detalhes de um comando específico.

O modo mais básico é rodar o comando run do menu interativo(help run para mais detalhes). Ele vai executar o código até o final ou até que um breakpoint seja encontrado. Nosso código não tem breakpoints ainda, então a execução irá até o fim.

phpdbg teste.php

[Welcome to phpdbg, the interactive PHP debugger, v7.4.3]
To get help using phpdbg type ?help? and press enter
[Please report bugs to http://bugs.php.net/report.php]
[Successful compilation of /home/leandro/Leandro/linux/teste.php]
prompt> run
total=62.7
[Script ended normally]
prompt>

Como podemos ver o resultado foi o mesmo obtido executando o script pela linha de comando. Podemos passar um argumento para o comando run, que será entendido como o argumento passado para o script na linha de comando , ou seja, seu argumento $argv (não usarei neste artigo).

Podemos ver o código fonte que estamos depurando usando o comando list. Podemos passar argumentos para esse comando, para sinalizar o que estamos querendo ver exatamente. Podemos ver linhas de código, funções, métodos ou uma classe inteira. Rode help list no menu interativo para mais detalhes. Nosso código não tem funções, por isso vamos analizar linhas de código. Para ver o código completo, podemos rodar:

phpdbg teste.php

[Welcome to phpdbg, the interactive PHP debugger, v7.4.3]
To get help using phpdbg type ?help? and press enter
[Please report bugs to http://bugs.php.net/report.php]
[Successful compilation of /home/leandro/Leandro/linux/teste.php]
prompt> list l 20
00001: 00002:
00003: $arr = [[3, 1.5], [5, 1.2], [10, 5], [2,1.1]];
00004:
00005: $total=0;
00006: foreach($arr as $val){
00007: $total = $val[0] * $val[1];
00008: }
00009:
00010: echo(?total=$total ?);
00011:
00012: ?>
00013:
prompt>


Veja que passamos o parâmetro 20, indicando que queremos ver 20 linhas, mas o código só tem 13 linhas. Sem problemas!

A quantidade de linhas se conta a partir da execução corrente, ou seja, em qual linha o código parou. Como o código não está em execução, a contagem é a partir do começo, se estivéssemos parados em um breakpoint, a contagem seria a partir da linha do breakpoint ou da linha que tivesse sendo executada por último, se usarmos a função step.

Agora vamos tentar corrigir nosso código. Como o valor total está incorreto, nossa suspeita é a de que a linha 7 ($total = $val[0] * $val[1];) está com problema. Vamos tentar descobrir qual é.

Essa linha está dentro de um loop foreach. Nosso plano, então, é setar um breakpoint na linha 7, iniciar a execução, esperar a interrupção e analisar o valor de $val[0], $val[1] e $total. Veremos se os valores do array $arr estão corretos e se a expressão completa está correta.

prompt> break 7
[Breakpoint #0 added at /home/leandro/Leandro/linux/teste.php:7]
prompt> run
[Breakpoint #0 at /home/leandro/Leandro/linux/teste.php:7, hits: 1]
00007: $total = $val[0] * $val[1];
00008: }
00009:


Nosso código rodou e parou na linha 7. Isso significa que a linha 7 não foi executada ainda.
Podemos visualizar o valor das variáveis com o comando ev no prompt (help ev para mais detalhes)o. Vamos analizar o valor de $val, $val[0], $val[1] e $total:

prompt> ev $val
Array
(
[0] => 3
[1] => 1.5
)
prompt> ev $val[0]
3
prompt> ev $val[1]
1.5
prompt> ev $total
0
prompt>


Podemos ver que os valores estão corretos, ou seja, não há erro de atribuição incorreta. São aqueles que nós estávamos esperando. Agora queremos executar o loop para analisar novamente essa linha.

Para isso, usamos o comando continue (help continue para mais detalhes) no prompt interativo. Poderíamos ter a situação de um bloco de código dentro do foreach com mais de um breakpoint. Se esse fosse o caso para o nosso codigo, a execução prosseguiria para esse novo breakpoint, até retornar para o início do bloco e para novamente em nosso breakpoint.

Podemos também rodar o código linha a linha através do comando step no menu interativo. Isso é mais útil em códigos complexos em que não sabemos exatamente onde pode estar o problema. Num artigo posterior faremos um exemplo com este comando.
Prosseguindo, temos:

prompt> continue
[Breakpoint #0 at /home/leandro/Leandro/linux/teste.php:7, hits: 2]
00007: $total = $val[0] * $val[1];
00008: }
00009:
prompt> ev $val
Array
(
[0] => 5
[1] => 1.2
)

prompt> ev $val[0]
5
prompt> ev $val[1]
1.2
prompt> ev $total
4.5
prompt>


Podemos ver que até aqui tudo está certo. Executemos mais uma vez então:

prompt> continue
[Breakpoint #0 at /home/leandro/Leandro/linux/teste.php:7, hits: 3]
00007: $total = $val[0] * $val[1];
00008: }
00009:
prompt> ev $val
Array
(
[0] => 10
[1] => 5
)

prompt> ev $val[0]
10
prompt> ev $val[1]
5
prompt> ev $total
6
prompt>


Aqui podemos ver que há um problema com a variável $total. Na execução anterior o valor era 4.5 e agora o valor é 6 e não 10.5! Ou seja, o valor da variável não está sendo incrementado no loop! De fato, podemos ver no código donte que isso não está acontecendo. Precisamos mudar a linha 7 de

$total = $val[0] * $val[1];

para

$total += $val[0] * $val[1];

Podemos encerrar a sessão atual com o comando quit, alterar o código fonte e carregar novamente o phpdbg. Mas se quisermos, podemos remover os breakpoints e rodar o código até o final, mas o código em execução ainda não conterá a modificação:

prompt> clear
Clearing Breakpoints
File 1
Functions 0
Methods 0
Oplines 0
File oplines 0
Function oplines 0
Method oplines 0
Conditionals 0
prompt> continue
total=2.2
[Script ended normally]
prompt>


Depois de efetuar a modificação, rodamos o código pela linha de comando e podemos verificar que a correção foi suficiente:

php teste.php

total=62.7

Assim nossa tarefa está concluída!

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Instalação
   3. Código de exemplo
   4. Sessão de debugação
   5. Conclusão
Outros artigos deste autor

Rodando um aplicativo em modo Kiosk no Ubuntu Linux 20.04

Leitura recomendada

Funções da categoria Miscelânea do PHP

Instalando a extensão json para o php-5.1 no CentOS/Red Hat

Criando um blog com o CakePHP 2.2.1

A simples classe Date Operations

Debian com Apache, PHP4, PHP5 e MySQL

  
Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário