Dissecando um inseto (ou como usar o pdb, the Python Debugger)

Boas, pessoal!

Hoje eu estou aqui pra mostrar como se usa o (básico do) Python Debugger, o pdb, que é (óbvio) um depurador pra se usar com o Python.
Este exemplo é feito usando o Python 3.


Mas... como é?


Bom, existe mais de uma maneira de usar o pdb. A que vou mostrar é chamando o pdb como um script para depurar outro script.

Então, primeiro, vamos criar um scriptosco com um erro mais tosco ainda pra gente começar a brincar com o pdb. O scriptosco é o seguinte:

#-*- coding: utf-8 -*-

def divide(a, b):
erro = False
try:
return float(a) / float(b)
except:
erro = True

if erro:
raise Exception("Não vou te dizer qual é o erro...")

a = 1
b = 2
divide(a, b)
a = 3
b = 0
divide(a, b)

Bom, rodando isso aí, a gente tem o seguinte:



$ $python3 exemplopdb.py
Traceback (most recent call last):
File "exemplopdb.py", line 18, in
divide(a, b)
File "exemplopdb.py", line 11, in divide
raise Exception("Não vou te dizer qual é o erro...")
Exception: Não vou te dizer qual é o erro...


Será que esse tal de pdb funciona mesmo?


Agora que temos um erro, podemos usar o pdb pra achar cara. A gente vai fingir que não vê nada errado até a hora certa, tá? :P
A sintexe pra se chamar o pdb é a seguinte:
python -m pdb <meu_script>
Então, ao chamar nosso doente junto com o pdb, a gente vai cair no shell do pdb. Assim:



$ python3 -m pdb exemplopdb.py
--Return--
> /media/5511fc83-ad85-484b-9b0e-0948abcb6026_/virtualpython/lib/python3.1/encodings/__init__.py(67)normalize_encoding()->'utf_32_be'
-> return ''.join(chars)
(Pdb)

Nós começaremos criando breakpoints nas linhas 11 e 18. Fazemos isto com o comando b[reak]. Depois, utilizando o comando c[ontinue], continuaremos a execução do programa até que algum breakpoint seja encontrado. E por fim, usaremos o comando list para listar um trecho de código e ver onde paramos.


(Pdb) break exemplopdb.py:11
Breakpoint 1 at /media/sda6/Projetos & afins/scripts/exemplopdb.py:11
(Pdb) b exemplopdb.py:18
Breakpoint 2 at /media/sda6/Projetos & afins/scripts/exemplopdb.py:18
(Pdb) c
> /media/sda6/Projetos & afins/scripts/exemplopdb.py(18)()
-> divide(a, b)
(Pdb) list
13 a = 1
14 b = 2
15 divide(a, b)
16 a = 3
17 b = 0
18 B-> divide(a, b)
19
[EOF]
(Pdb)

Nosso primeiro breakpoint é bem na chamada da função, então vamos "entrar na função" e acompanhar a execução. A gente faz isso com o comando s[tep]. Uma vez na função, a gente pode acompanhar a execução linha-por-linha usando o comando n[ext] e também pode imprimir os valores das variáveis com print.


(Pdb) s
--Call--
> /media/sda6/Projetos & afins/scripts/exemplopdb.py(3)divide()
-> def divide(a, b):
(Pdb) list
1 #-*- coding: utf-8 -*-
2
3 -> def divide(a, b):
4 erro = False
5 try:
6 return float(a) / float(b)
7 except:
8 erro = True
9
10 if erro:
11 B raise Exception("Não vou te dizer qual é o erro...")
(Pdb) n
> /media/sda6/Projetos & afins/scripts/exemplopdb.py(4)divide()
-> erro = False
(Pdb) n
> /media/sda6/Projetos & afins/scripts/exemplopdb.py(5)divide()
-> try:
(Pdb) n
> /media/sda6/Projetos & afins/scripts/exemplopdb.py(6)divide()
-> return float(a) / float(b)
(Pdb) print(a, b)
(3, 0)
(Pdb) n
ZeroDivisionError: 'float division'
> /media/sda6/Projetos & afins/scripts/exemplopdb.py(6)divide()
-> return float(a) / float(b)
(Pdb)

Bom, aí matamos o erro, não? Funciona mesmo!

Moral da história: As vezes o pdb pode salvar várias horas do seu dia. Faça dele um amigo. :)

Comentários

Faça seu comentário