[Python] pdb를 이용해 파이썬 코드 디버깅하기

pdb를 이용해 python 코드를 디버깅하는 방법을 알아보자.


환경

  • Linux 기반 시스템
  • Bash shell(/bin/bash)
  • Python


pdb

pdb란?

  • pdb: 파이썬 디버깅 도구로 파인썬 인터프리터를 줄마다 보면서 실행할 수 있도록 도와주는 도구입니다.


실행 방법

pdb 실행방법 - 1

  • 처음부터 코드를 실행할 때 사용
python3 -m pdb example.py
  • 실행 예제
$ python -m pdb test.py
> /Users/taewoo/test.py(1)<module>()
-> def test_sum(a,b):
(Pdb)

pdb 실행방법 - 2

  • 코드의 특정 부분부터 사용
# In python code
...
import pdb; pdb.set_trace()
...
  • 실행 예제
$ python test.py
> /Users/taewoo/test.py(6)<module>()
-> b=30
(Pdb)


사용법

사용 명령어 목록

  • l: 주변 소스코드들을 출력하며 현재 라인이 화살표로 나옵니다.
  • n: 다음 문장으로 이동합니다. 즉, 위에 l에서 위치한 부분을 실행하고 다음 명령어줄로 가는겁니다.
  • s: 흔히 사용하는 ‘Step Into’로 함수 내부로 들어갑니다. --Call--이라고 나오며 다 진행된 후에는 --Return--이 나옵니다.
  • c: 다음줄부터 중단점을 만날때까지 코드를 실행하며 중단점이 없다면 끝까지 실행합니다.
  • r: 현재 함수의 return이 나올때까지 실행합니다.
  • w: 함수의 call stack을 보여줍니다.
  • cl: 모든 중단점들을 삭제합니다.
  • b: 특정파일이나 패키지의 줄번호나 함수명으로 중단점을 만들 수 있습니다.
  • a: 현재 함수의 매개변수들을 출력.

사용 명령어 예제

  • l: 주변 소스코드들을 출력하며 현재 라인이 화살표로 나옵니다.
(Pdb) l
  1  	def test_sum(a,b):
  2  	    return a+b
  3
  4  	a=10
  5  ->	b=30
  6  	c=test_sum(a,b)
  7
  8  	for i in range(1,10):
  9  	    a = a + i
 10
 11  	import requests
  • n: 다음 문장으로 이동합니다. 즉, 위에 l에서 위치한 부분을 실행하고 다음 명령어줄로 가는겁니다.
(Pdb)  n
> /Users/taewoo/test.py(6)<module>()
-> c=test_sum(a,b)
  • s: 흔히 사용하는 ‘Step Into’로 함수 내부로 들어갑니다. --Call--이라고 나오며 다 진행된 후에는 --Return--이 나옵니다.
(Pdb)  s
--Call--
> /Users/taewoo/test.py(1)test_sum()
-> def test_sum(a,b):
...
--Return--
> /Users/taewoo/test.py(5)test_sum()->40
-> return a+b
  • c: 다음줄부터 중단점을 만날때까지 코드를 실행하며 중단점이 없다면 끝까지 실행합니다.
(Pdb) c
The program finished and will be restarted
  • r: 현재 함수의 return이 나올때까지 실행합니다.
(Pdb) s
--Call--
> /Users/taewoo/test.py(1)test_sum()
-> def test_sum(a,b):
(Pdb) r
--Return--
> /Users/taewoo/test.py(5)test_sum()->40
-> return a+b
  • w: 함수의 call stack을 보여줍니다.
(Pdb) w
  /Users/taewoo/.pyenv/versions/3.6.2/lib/python3.6/bdb.py(431)run()
-> exec(cmd, globals, locals)
  <string>(1)<module>()
  /Users/taewoo/test.py(9)<module>()
-> c=test_sum(a,b)
> /Users/taewoo/test.py(5)test_sum()->40
-> return a+b
  • cl: 모든 중단점들을 삭제합니다.
(Pdb) cl
Clear all breaks? y
  • b: 특정파일이나 패키지의 줄번호나 함수명으로 중단점을 만들 수 있습니다.
(Pdb) b 8
Breakpoint 1 at /Users/taewoo/test.py:8
(Pdb) b test_sum
Breakpoint 2 at /Users/taewoo/test.py:1
# Stop at line number 8
(Pdb) c
> /Users/taewoo/test.py(8)<module>()
-> b=30
# Stop at function
(Pdb) c
> /Users/taewoo/test.py(2)test_sum()
-> tmp=1
(Pdb) b
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at /Users/taewoo/test.py:8
	breakpoint already hit 2 times
2   breakpoint   keep yes   at /Users/taewoo/test.py:1
	breakpoint already hit 1 time
  • a: 현재 함수의 매개변수들을 출력.
(Pdb)  s
--Call--
> /Users/taewoo/test.py(1)test_sum()
-> def test_sum(a,b):
(Pdb) a
a = 10
b = 30

기타

  • 변수 값을 확인하고 싶을때 해당 변수를 명령어처럼 입력하던가 print함수를 이용할 수 있습니다.
(Pdb) c
> /Users/taewoo/test.py(2)test_sum()
-> tmp=1
(Pdb) n
> /Users/taewoo/test.py(3)test_sum()
-> tmp=2
(Pdb) tmp
1
(Pdb) print(tmp)
1
(Pdb) type(data)
<class 'dict'>
(Pdb) data
{'data': [{'type': 'articles', 'id': '1', 'attributes': {'title': 'JSON API paints my bikeshed!', 'body': 'The shortest article. Ever.', 'created': '2015-05-22T14:56:29.000Z', 'updated': '2015-05-22T14:56:28.000Z'}, 'relationships': {'author': {'data': {'id': '42', 'type': 'people'}}}}], 'included': [{'type': 'people', 'id': '42', 'attributes': {'name': 'John', 'age': 80, 'gender': 'male'}}]}
  • 코드 상에 중단점 추가하기
  • 코드 중간에 import pdb; pdb.set_trace()를 추가하면 해당 부분에서 멈춥니다.
def test_sum(a,b):
    tmp=1
    tmp=2
    tmp=3
    return a+b

a=10
b=30
c=test_sum(a,b)

for i in range(1,10):
    a = a + i

import requests
import pdb; pdb.set_trace()
url = 'https://gist.githubusercontent.com/TWpower/771f9dfc8d9e1ddc0ecbdaea5b2e379e/raw/2c7785b4835138255bdadb71bd83702e53ac2677/test-example.json'

data = requests.get(url).json()
$ python -m pdb test.py
> /Users/taewoo/test.py(1)<module>()
-> def test_sum(a,b):
(Pdb) c
> /Users/taewoo/test.py(16)<module>()
-> url = 'https://gist.githubusercontent.com/TWpower/771f9dfc8d9e1ddc0ecbdaea5b2e379e/raw/2c7785b4835138255bdadb71bd83702e53ac2677/test-example.json'
(Pdb)


참고자료