본문 바로가기
개발

리눅스에서 커맨드라인으로 파이썬 디버깅 하기 - PDB(Python Debugger)

by developer's warehouse 2024. 6. 3.

리눅스 서버에서 파이썬 개발을 하다 보면 종종 커맨드라인 환경에서 작업을 해야 하는 상황에 직면합니다. 특히, GUI 개발 도구를 사용할 수 없는 리눅스 서버에서 디버깅을 해야 할 때, 이는 더 중요해집니다. 이러한 환경에서 효율적으로 문제를 해결하기 위해 필수적인 도구 중 하나가 바로 PDB(Python Debugger)입니다.

저는 데이터 처리 파이썬 스크립트를 작성하던 중, 예상치 못한 오류로 인해 무한 루프에 빠지는 문제를 겪었습니다. 당시, 리눅스 서버에서 작업하고 있었기 때문에 GUI 기반의 디버깅 도구를 사용할 수 없었습니다. 출력을 통해 문제를 추적하려고 했지만, 문제의 근원을 파악하기에는 부족함이 있었습니다.

이때 PDB를 사용하여 디버깅을 시도했습니다. PDB를 통해 코드의 실행을 한 줄씩 따라가면서 변수의 상태를 실시간으로 확인하고, 함수 호출 스택을 조사하며, 특정 지점에서 코드 실행을 멈추는 등의 기능을 활용했습니다. 이러한 과정을 통해 문제의 원인을 찾아낼 수 있었고, 특정 함수에서 발생한 논리 오류를 수정할 수 있었습니다.

PDB를 사용한 디버깅 과정은 마치 코드와 직접 대화를 나누는 듯한 경험이었습니다. 코드의 흐름을 세밀하게 추적하면서 문제를 해결해 나가는 과정은 매우 편리했고, 커맨드라인 환경에서도 효과적으로 디버깅을 할 수 있다는 사실을 알게 되습니다.

이 글에서는 커맨드라인 환경에서 GUI 개발 도구 없이 PDB를 사용하여 버그를 해결하는 방법에 대해 요약해 드리려고합니다. 여러분도 PDB의 강력한 기능을 활용하여 커맨드라인 환경에서의 디버깅 능력을 향상하고, 더 나은 파이썬 개발자가 되길 바랍니다.

리눅스에서 커맨드라인으로 파이썬 디버깅 하기 - PDB(Python Debugger) 썸네일

PDB 란?

PDB(Python Debugger)는 파이썬 내장 디버거로, 파이썬 코드의 실행을 제어하고 오류를 찾아 수정하는 데 도움을 주는 도구입니다. PDB는 파이썬 스크립트를 디버깅할 때 매우 유용하며, 특히 커맨드라인 환경에서 GUI 디버깅 도구를 사용할 수 없을 때 매우 편리합니다. PDB를 사용하면 코드의 실행을 한 줄씩 따라가며 변수의 상태를 확인하고, 함수 호출 스택을 조사하며, 특정 지점에서 코드 실행을 멈추는 등의 작업을 수행할 수 있습니다.

주요 기능

  • 중단점 설정: 코드 실행 중 특정 지점에서 실행을 멈추고 상태를 조사할 수 있습니다.
  • 한 줄씩 실행: 코드를 한 줄씩 실행하며 코드의 흐름을 상세히 추적할 수 있습니다.
  • 함수 내부로 진입: 함수 호출 시 함수 내부로 들어가 실행 과정을 자세히 살펴볼 수 있습니다.
  • 변수 값 확인 및 수정: 실행 중인 프로그램의 변수 값을 실시간으로 확인하고 수정할 수 있습니다.
  • 콜 스택 조사: 코드 실행 중 콜 스택을 확인하여 함수 호출 관계와 현재 실행 위치를 파악할 수 있습니다.

사용 방법

PDB를 사용하려면 코드에 import pdb; pdb.set_trace()를 삽입하여 중단점을 설정하거나, 커맨드라인에서 파이썬 스크립트를 실행할 때 -m pdb 옵션을 사용할 수 있습니다.

1. 코드 변경없이 바로 사용하기

커맨드라인에서 다음과 같이 -m 옵션을 사용하여 간단하게 사용할 수 있습니다.

python -m pdb my_script.py

 

아래는 test.py라는 간단한 파이썬 스크립트 파일을 -m pdb 옵션으로 디버깅 실행한 예제입니다.

% cat test.py
def my_function():
    a = 10
    b = 20
    c = a + b
    print(c)

my_function()

% python3 -m pdb test.py
> /redis/redis-rb-cluster/test.py(2)<module>()
-> def my_function():
(Pdb) l
  1
  2  -> def my_function():
  3         a = 10
  4         b = 20
  5         c = a + b
  6         print(c)
  7
  8     my_function()
  9
[EOF]

2. 코드에 중단점 설정하기

코드에 디버깅을 시작하려는 지점에 set_trace를 통해서 브레이크포인트를 설정하여 pdb 디버깅을 할 수 있습니다.

아래처럼 코드에 pdb의 set_trace() 메서드를 호출하면 실행 시 해당 위치에서 멈추고 pdb 대화창이 수행됩니다.

<test.py 파일>
import pdb

def my_function():
    a = 10
    b = 20
    pdb.set_trace()  # 여기서 코드 실행이 중단됩니다.
    c = a + b
    print(c)

my_function()

<실행 결과>
% python3 test.py
> /redis/redis-rb-cluster/test.py(7)my_function()
-> c = a + b
(Pdb)

 

자주 사용되는 PDB 명령어

아래는 자주 사용되는 PDB 명령어들을 정리한 표입니다.

명령어 실행 내용
help 도움말
next (n) 다음 문장으로 이동
print (p) 변수값 화면에 표시
list (l) 소스코드 리스트 출력, 현재 위치 화살표로 표시됨
where (w) 콜스택 출력
continue (c) 계속 실행, 다음 중단점에 멈추거나 중단점 없으면 끝까지 실행
step (s) Step Into 하여 함수 내부로 들어감
return (r) 현재 함수의 리턴 직전까지 실행
!변수명 = 값 변수에 값 재설정
cl 모든 중단점 삭제
b 특정 파일이나 패키지의 줄번호나 함수명으로 중단점 생성
a 현재 함수의 매개변수 출력
EOF PDB 세션 종료
d 한 단계 아래로 이동 (down)
h 도움말
ll 현재 함수의 모든 소스코드 리스트 출력 (long list)
q 디버거 종료 (quit)
rv 함수 리턴값 표시 (retval)
undisplay 모든 표시된 변수들 해제
clear 특정 중단점 삭제
disable 특정 중단점 비활성화
ignore 특정 중단점 무시할 횟수 설정
restart 프로그램 재시작
source 소스코드 파일 경로 출력
unt 특정 줄까지 실행 (until)
up (u) 한 단계 위로 이동
whatis 변수의 타입 출력

 

위의 명령어들은 PDB 디버거에서 자주 사용하는 주요 명령어들을 포함하고 있습니다. 추가적인 명령어와 세부 사항은 help <topic> 명령어를 통해 자세히 확인할 수 있습니다.

 

위의 명령어들을 이용해서 제가 작성한 example.py 코드를 디버깅하는 예제는 아래에 첨부하였으니 참고하세요.

% python3 -m pdb example.py
> /redis/redis-py-cluster/example.py(1)<module>()
-> import time
(Pdb) l
  1  -> import time
  2
  3     from rediscluster import RedisCluster
  4
  5     # Redis cluster conf
  6     startup_nodes = [
  7         {"host": "127.0.0.1", "port": "30001"},
  8         {"host": "127.0.0.1", "port": "30002"},
  9         {"host": "127.0.0.1", "port": "30003"}
 10     ]
 11
(Pdb) n
> /redis/redis-py-cluster/example.py(3)<module>()
-> from rediscluster import RedisCluster
(Pdb) n
> /redis/redis-py-cluster/example.py(7)<module>()
-> {"host": "127.0.0.1", "port": "30001"},
(Pdb) n
> /redis/redis-py-cluster/example.py(8)<module>()
-> {"host": "127.0.0.1", "port": "30002"},
(Pdb) n
> /redis/redis-py-cluster/example.py(9)<module>()
-> {"host": "127.0.0.1", "port": "30003"}
(Pdb) n
> /redis/redis-py-cluster/example.py(21)<module>()
-> last = 0
(Pdb) help

Documented commands (type help <topic>):
========================================
EOF    c          d        h         list      q        rv       undisplay
a      cl         debug    help      ll        quit     s        unt
alias  clear      disable  ignore    longlist  r        source   until
args   commands   display  interact  n         restart  step     up
b      condition  down     j         next      return   tbreak   w
break  cont       enable   jump      p         retval   u        whatis
bt     continue   exit     l         pp        run      unalias  where

Miscellaneous help topics:
==========================
exec  pdb

(Pdb) n
> /p3700/lswhh/redis/redis-py-cluster/example.py(17)<module>()
-> while not last:
(Pdb) n
> /p3700/lswhh/redis/redis-py-cluster/example.py(18)<module>()
-> try:
(Pdb) list
 13     rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
 14
 15     last = False
 16
 17     while not last:
 18  ->     try:
 19             last = rc.get("__last__")
 20             if not last:
 21                 last = 0
 22         except Exception as e:
 23             print(f"error {str(e)}")
(Pdb) p last
0

 

오늘은 리눅스나 GUI 툴이 없을 때, 간단하고 편리하게 파이썬 스크립트를 디버깅할 수 있는 파이썬 기본 디버거인 PDB에 대해서 알아보았습니다. GUI 없어도 간단하게 디버깅할 수 있으니 강력한 언어인 파이썬으로 원하는 문제를 해결해 보시기 바래요.

 

참고자료

파이썬 공식 문서: pdb — 파이썬 디버거 — Python 3.12.3 문서

facebook twitter kakaoTalk kakaostory naver band shareLink