소프트웨어 개발 분야에서 디버깅(debugging)은 프로그램 내 오류를 찾아내고 수정하는 과정을 의미하는 용어로 널리 사용됩니다. 파이썬의 표준 라이브러리에는 파이썬 프로그램의 디버깅을 위한 다양한 유틸리티를 제공하는 pdb 모듈이 포함되어 있습니다.
pdb의 디버깅 기능은 Pdb 클래스에 정의되어 있으며, 이 모듈은 내부적으로 bdb와 cmd 모듈을 활용합니다.
pdb 디버거 시작하기
pdb 모듈은 매우 편리한 명령줄 인터페이스를 제공합니다. 파이썬 스크립트를 실행할 때 -m 옵션을 사용하면 디버거가 함께 실행됩니다.
python -m pdb script.py
예제 코드 작성
디버거가 어떻게 동작하는지 살펴보기 위해 먼저 다음과 같은 파이썬 모듈(fact.py)을 작성해 보겠습니다.
def fact(x):
f = 1
for i in range(1,x+1):
print (i)
f = f * i
return f
if __name__=="__main__":
print ("factorial of 3=",fact(3))명령줄에서 이 모듈의 디버깅을 시작하면, 코드의 첫 번째 줄에서 실행이 멈추고 해당 줄 왼쪽에 화살표(->)가 표시되며 디버거 프롬프트(Pdb)가 나타납니다.
C:\python36>python -m pdb fact.py > c:\python36\fact.py(1)<module>() -> def fact(x): (Pdb)
주요 디버거 명령어
help와 list
모든 디버거 명령어 목록을 확인하려면 디버거 프롬프트 앞에 help를 입력하세요. 특정 명령어에 대한 자세한 정보가 필요하면 help <command> 형식으로 입력하면 됩니다.
list 명령어는 전체 코드를 출력하며, 프로그램이 현재 멈춰 있는 줄의 왼쪽에는 ->
(Pdb) list
1 -> def fact(x):
2 f = 1
3 for i in range(1,x+1):
4 print (i)
5 f = f * i
6 return f
7 if __name__=="__main__":
8 print ("factorial of 3 = ", fact(3))step과 next
프로그램을 한 줄씩 진행하려면 step 또는 next 명령어를 사용합니다.
(Pdb) step
> c:\python36\fact.py(7)<module>()
-> if __name__=="__main__":
(Pdb) next
> c:\python36\fact.py(8)<module>()
-> print ("factorial of 3 = ", fact(3))
(Pdb) next
1
2
3
factorial of 3= 6
--Return--
> c:\python36\fact.py(8)<module>()->None
-> print ("factorial of 3 = ", fact(3))step과 next의 가장 큰 차이점은 다음과 같습니다. step 명령어는 함수 내부로 들어가 그 안에서 프로그램을 멈추는 반면, next 명령어는 호출된 함수를 한 번에 실행하고 함수가 끝난 후에 멈춥니다.
C:\python36>python -m pdb fact.py
> c:\python36\fact.py(1)<module>()
-> def fact(x):
(Pdb) s
> c:\python36\fact.py(7)<module>()
-> if __name__=="__main__":
(Pdb) n
> c:\python36\fact.py(8)<module>()
-> print ("factorial of 3=",fact(3))
(Pdb) s
--Call--
> c:\python36\fact.py(1)fact()
-> def fact(x):
(Pdb) n
> c:\python36\fact.py(2)fact()
-> f = 1
(Pdb) n
> c:\python36\fact.py(3)fact()
-> for i in range(1,x+1):
(Pdb) n
> c:\python36\fact.py(4)fact()
-> print (i)
(Pdb) n
1
> c:\python36\fact.py(5)fact()
-> f = f * i
(Pdb) n
> c:\python36\fact.py(3)fact()
-> for i in range(1, x + 1):
(Pdb) n
> c:\python36\fact.py(4)fact()
-> print (i)
(Pdb) f,i
(1, 2)
(Pdb)step 명령어는 프로그램이 함수 호출을 만나면 --Call-- 표시를, 함수가 종료되면 --Return-- 표시를 보여줍니다. 또한 언제든지 변수 이름만 입력하면 해당 변수의 값을 확인할 수 있습니다.
break — 중단점 설정
break 명령어를 사용하면 프로그램 내에 중단점(breakpoint)을 설정할 수 있습니다. 이때 중단점을 설정할 줄 번호를 반드시 지정해야 합니다. 예를 들어 break 5를 입력하면 현재 프로그램의 5번째 줄에 중단점이 설정됩니다.
(Pdb) list
2 f = 1
3 for i in range(1, x + 1):
4 print (i)
5 f = f * i
6 return f
7 -> if __name__=="__main__":
8 print ("factorial of 3=",fact(3))
[EOF]
(Pdb) break 5
Breakpoint 1 at c:\python36\fact.py:5
(Pdb) continue
1
> c:\python36\fact.py(5)fact()
-> f = f * i
(Pdb) break
Num Type Disp Enb Where
1 breakpoint keep yes at c:\python36\fact.py:5
breakpoint already hit 1 time
(Pdb) continue
2
> c:\python36\fact.py(5)fact()
-> f = f * i
(Pdb) b
Num Type Disp Enb Where
1 breakpoint keep yes at c:\python36\fact.py:5
breakpoint already hit 2 timescontinue 명령어를 실행하면 프로그램이 중단점을 만날 때까지 계속 진행됩니다. 설정된 모든 중단점을 확인하려면 줄 번호 없이 break 명령어만 입력하면 됩니다.
disable / enable / clear
중단점은 disable/enable 명령어로 비활성화하거나 다시 활성화할 수 있으며, clear 명령어로 완전히 삭제할 수도 있습니다.
(Pdb) disable 1 Disabled breakpoint 1 at c:\python36\fact.py:5 (Pdb) b Num Type Disp Enb Where 1 breakpoint keep no at c:\python36\fact.py:5 breakpoint already hit 2 times
스크립트 내부에서 pdb 사용하기
pdb 디버거는 파이썬 스크립트 안에서도 사용할 수 있습니다. 이 경우 스크립트 상단에 pdb를 임포트하고, 프로그램 내에서 set_trace() 메서드를 호출하면 됩니다.
import pdb
def fact(x):
f = 1
for i in range(1,x+1):
pdb.set_trace()
print (i)
f = f * i
return f
if __name__=="__main__":
print ("factorial of 3=",fact(3))이렇게 하면 디버거의 동작이 명령줄 환경에서 실행했을 때와 정확히 동일하게 나타납니다. 코드 실행 중 특정 지점에서 자동으로 디버거가 시작되기를 원한다면 이 방법이 매우 유용합니다.