# `pdb` — 파이썬 디버거

소스 코드: Lib/pdb.py

`pdb` 모듈은 파이썬 프로그램을 위한 대화형 소스 코드 디버거를 정의합니다. 소스 라인 단계의 중단점(breakpoint) 및 단계 실행(single stepping) 설정, 스택 프레임 검사, 소스 코드 목록, 그리고 모든 스택 프레임의 컨텍스트에서 임의의 파이썬 코드 평가를 지원합니다. 또한 포스트-모템(post-mortem) 디버깅을 지원하며, 프로그램 제어 하에서도 호출될 수 있습니다.

이 디버거는 확장이 가능합니다 – 디버거는 실제로 `Pdb` 클래스로 정의됩니다. 현재 문서화되어 있진 않지만, 소스를 읽어보시면 쉽게 이해하실 수 있습니다. 확장 인터페이스는 `bdb` 와 `cmd` 모듈을 활용합니다.

디버거의 프롬프트는 `(Pdb)` 입니다. 디버거 제어하에 프로그램을 실행하는 일반적인 사용법은 다음과 같습니다:

    >>> import pdb
    >>> import mymodule
    >>> pdb.run('mymodule.test()')
    > <string>(0)?()
    (Pdb) continue
    > <string>(1)?()
    (Pdb) continue
    NameError: 'spam'
    > <string>(1)?()
    (Pdb)

버전 3.3에서 변경: `readline` 모듈을 통한 탭-완성은 명령과 명령 인자에 사용할 수 있습니다, 예를 들면, 현재 전역 및 지역 이름들은 `p` 명령의 인자로 제공됩니다.

`pdb.py` 는 다른 스크립트를 디버그하기 위한 스크립트로 호출될 수 있습니다. 예를 들면:

    python3 -m pdb myscript.py

스크립트로 호출하는 경우, 디버깅 중인 프로그램이 비정상적으로 종료되면 pdb는 자동으로 포스트-모템(post-mortem) 디버깅을 시작합니다. 포스트-모템 디버깅이 끝나면 (또는 프로그램이 정상적으로 종료되면), pdb는 프로그램을 재시작합니다. 자동 재시작은 중단점과 같은 pdb의 상태를 유지하고 대부분의 경우 프로그램 종료 시 디버거를 종료하는 것보다 유용합니다.

버전 3.2에 추가: `pdb.py` 는 이제 `.pdbrc` 파일에 주어진 것처럼 명령을 실행하는 `-c` 옵션을 받을 수 있습니다, 디버거 명령들 을 확인해보세요.

버전 3.7에 추가: `pdb.py` 는 이제 `python3 -m`과 비슷한 모듈을 실행하는 `-m` 옵션을 받을 수 있습니다. 스크립트와 마찬가지로, 디버거는 모듈의 첫 번째 줄 바로 전에 실행을 일시정지합니다.

실행 중인 프로그램에서 디버거로 진입하는 일반적인 사용법은:

    import pdb; pdb.set_trace()

위 코드를 디버거로 진입하고 싶은 구간에 추가하면 됩니다. 그런 다음 이 문장 뒤에 오는 코드를 단계별로 실행하고, `continue` 명령을 사용하여 디버거 없이 프로그램을 계속 실행할 수 있습니다.

버전 3.7에 추가: 내장 `breakpoint()`가, 기본값으로 호출될 때는, `import pdb; pdb.set_trace()`를 대신해서 사용할 수 있습니다.

에러가 발생하는 프로그램을 검사하는 일반적인 사용법은 다음과 같습니다:

    >>> import pdb
    >>> import mymodule
    >>> mymodule.test()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "./mymodule.py", line 4, in test
        test2()
      File "./mymodule.py", line 3, in test2
        print(spam)
    NameError: spam
    >>> pdb.pm()
    > ./mymodule.py(3)test2()
    -> print(spam)
    (Pdb)

이 모듈은 다음과 같은 함수를 정의합니다; 각 함수는 조금 다른 방식으로 디버거로 진입합니다:

`pdb.``run`(statement, globals=None, locals=None)

  디버거 제어하에 statement (주어진 문자열 또는 코드 객체)를 실행합니다. 코드가 실행하기 전에 디버거 프롬프트가 나타납니다; 중단점을 지정하고 `continue`를 입력하거나, `step` 또는 `next`를 통해 문장을 단계별로 살펴볼 수 있습니다. (이 모든 명령은 아래에 설명되어 있습니다.) 선택적 인자 globals 와 locals는 코드가 실행되는 환경을 구체적으로 명시합니다; 기본적으로는 이 모듈의 딕셔너리 `__main__` 이 사용됩니다. (내장 함수 `exec()` 또는 `eval()` 에 대한 설명 참조.)

`pdb.``runeval`(expression, globals=None, locals=None)

  디버거 제어하에 문자열 또는 코드 객체로 주어진 expression을 평가합니다. `runeval()` 이 반환될 때, 표현식의 값을 반환합니다. 그렇지 않으면 이 함수는 `run()`과 유사한 함수입니다.

`pdb.``runcall`(function, *args, **kwds)

  주어진 인자와 함께 function (문자열이 아닌, 함수 또는 메서드 객체)를 호출합니다. `runcall()` 이 반환될 때, 함수 호출로 반환된 값을 반환합니다. 디버거 프롬프트는 함수에 진입하자마자 나타납니다.

`pdb.``set_trace`(*, header=None)

  호출하는 스택 프레임에서 디버거에 진입합니다. 코드가 디버그 되지 않는 경우 일지라도 (예를 들면, assertion이 실패하는 경우), 프로그램의 특정 지점에 중단점을 하드 코딩할 때 유용하게 사용됩니다. header 값을 주면, 디버깅이 시작되기 바로 전에 그 값이 콘솔에 출력됩니다.

  버전 3.7에서 변경: 키워드 전용 인자 header.

`pdb.``post_mortem`(traceback=None)

  주어진 traceback 객체의 포스트-모템(post-mortem) 디버깅으로 진입합니다. 만약 traceback이 주어지지 않았다면, 현재 처리되고 있는 하나의 예외를 사용합니다. (기본값을 사용하는 경우 예외는 반드시 처리되고 있어야 합니다.)

`pdb.``pm`()

  `sys.last_traceback` 에서 찾은 traceback 의 포스트-모템(post-mortem) 디버깅으로 진입합니다.

`run*` 함수와 `set_trace()`는 `Pdb` 클래스를 인스턴스 화하고 같은 이름의 메서드를 호출하는 에일리어스(alias) 입니다. 더 많은 기능에 액세스하려면, 아래를 참고하여 직접 하셔야 합니다:

class `pdb.``Pdb`(completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True)

  `Pdb` 는 디버거 클래스입니다.

  completekey, stdin 그리고 stdout 인자는 내부 `cmd.Cmd` 클래스로 전달됩니다; 자세한 설명은 해당 클래스에서 확인할 수 있습니다.

  skip 인자가 주어진다면, 반드시 글로브-스타일(glob-style) 모듈 이름 패턴의 이터러블(iterable) 이어야 합니다. 디버거는 이 패턴 중 하나와 일치하는 모듈에서 시작되는 프레임 단계로 들어가지 않습니다. 1

  기본적으로, Pdb는 사용자가 `continue` 명령을 내릴 때, SIGINT 신호(사용자가 콘솔에서 `Ctrl-C`를 누를 때 전송되는 신호) 에 대한 핸들러를 설정합니다. 사용자는 `Ctrl-C`를 눌러서 디버거를 벗어날 수 있습니다. 만약 Pdb가 SIGINT 핸들러를 건드리지 않길 원한다면 nosigint 설정을 참으로 변경하면 됩니다.

  readrc 인자는 기본적으로 참이고 Pdb가 파일 시스템으로부터 .pdbrc를 불러올지 여부를 제어합니다.

  skip으로 추적하기 위한 호출 예시:

      import pdb; pdb.Pdb(skip=['django.*']).set_trace()

  인자 없이 감사 이벤트 `pdb.Pdb`를 발생시킵니다.

  버전 3.1에 추가: skip 인자.

  버전 3.2에 추가: nosigint 인자. 이전에는, Pdb가 SIGINT 핸들러를 설정하지 않았습니다.

  버전 3.6에서 변경: readrc 인자.

  `run`(statement, globals=None, locals=None)
  `runeval`(expression, globals=None, locals=None)
  `runcall`(function, *args, **kwds)
  `set_trace`()

    위에 설명된 함수에 대한 설명서를 참조하시면 됩니다.

## 디버거 명령들

디버거가 인식할 수 있는 명령이 아래 나열되어 있습니다. 대부분의 명령은 한두 문자로 단축될 수 있습니다; 예를 들면, `h(elp)` 는 `h` 또는 `help`로 help 명령을 입력할 때 사용할 수 있습니다. (하지만 `he`, `hel`, `H`, `Help` 또는 `HELP`는 사용할 수 없습니다.) 인자는 반드시 명령과 공백(스페이스나 탭)으로 분리되어야 합니다. 선택적 인자는 명령 문법에서 대괄호(`[]`)로 묶여있습니다; 대괄호는 입력하지 않습니다. 명령 문법에서 대체 가능한 인자는 세로 바(`|`)로 분리되어 있습니다.

빈 줄을 입력하면 마지막으로 입력된 명령이 반복됩니다. 예외: 만약 마지막 명령이 `list` 명령이면, 다음 11줄이 나열됩니다.

디버거가 인식하지 못하는 명령은 파이썬 문장으로 가정하고 디버깅 중인 프로그램의 컨텍스트에서 실행됩니다. 파이썬 문장 앞에 느낌표(`!`)를 붙여 사용할 수도 있습니다. 이 방법은 디버깅 중인 프로그램을 검사하는 강력한 방법입니다. 변수를 변경하거나 함수를 호출하는 것도 가능합니다. 이 문장에서 예외가 발생하면, 예외 명은 출력되지만 디버거의 상태는 변경되지 않습니다.

디버거는 에일리어스을 지원합니다. 에일리어스는 검사 중인 컨텍스트에서 특정 수준의 적응성을 허용하는 매개변수를 가질 수 있습니다.

한 줄에 여러 명령은 `;;` 로 구분하여 입력할 수 있습니다. (단일 `;` 는 파이썬 파서로 전달되는 한 줄에서, 여러 명령을 구분하기 위한 분리 기호이므로 사용되지 않습니다.) 명령을 똑똑하게 분리하진 못합니다; 입력의 맨 처음 `;;` 에서 나뉘며, 따옴표로 묶인 문자열 중간에 있더라도 나눠집니다.

만약 파일 `.pdbrc` 가 사용자의 홈 디렉터리 또는 현재 디렉터리에 있으면, 디버거 프롬프트에서 입력된 것처럼 읽히고 실행됩니다. 이것은 특히 에일리어스에 유용합니다. 만약 두 파일이 모두 존재하면, 홈 디렉터리에 있는 파일이 먼저 읽히고 거기에 정의된 에일리어스는 로컬 파일에 의해 무시될 수 있습니다.

버전 3.2에서 변경: `.pdbrc` 는 `continue`와 `next`같이 디버깅을 계속하는 명령을 포함할 수 있습니다. 이전에는, 이런 명령이 효과가 없었습니다.

`h(elp)``[command]`

  인자가 없는 경우에는, 사용 가능한 명령 리스트를 출력합니다. command 인자가 주어진 경우에는, 해당 명령의 도움말을 출력합니다. `help pdb` 는 전체 문서(`pdb` 모듈의 독스트링)를 표시합니다. command 인자는 반드시 식별자이어야 하므로, `!` 명령의 도움말을 얻기 위해서 `help exec` 가 꼭 입력되어야 합니다.

`w(here)`

  가장 최근 프레임을 맨 아래로 하는 스택 트레이스를 출력합니다. 화살표는 현재 프레임을 나타내며, 대부분의 명령의 컨텍스트를 명확히 합니다.

`d(own)``[count]`

  스택 트레이스에서 현재 프레임을 count (기본 1) 단계 아래로 (새로운 프레임으로) 이동합니다.

`u(p)``[count]`

  스택 트레이스에서 현재 프레임을 count (기본 1) 단계 위로 (이전 프레임으로) 이동합니다.

`b(reak)``[([filename:]lineno | function) [, condition]]`

  lineno 인자가 주어진 경우, 현재 파일의 해당 줄 번호에 브레이크를 설정합니다. function 인자가 주어진 경우, 함수 내에서 첫 번째 실행 가능한 문장에서 브레이크를 설정합니다. 줄 번호는 다른 파일 (아마도 아직 로드되지 않은 파일)에 중단점을 지정하기 위해, 파일명과 콜론을 접두사로 사용할 수 있습니다. 파일은 `sys.path` 에서 검색합니다. 주의할 점은 각 중단점에 번호가 지정되며, 다른 모든 중단점 명령이 그 번호를 참조하게 됩니다.

  두 번째 인자가 있는 경우, 중단점을 적용하기 전에 표현식이 반드시 참이어야 합니다.

  인자가 없다면, 각 중단점, 중단점에 도달한 횟수, 현재까지 무시 횟수, 그리고 관련 조건(있는 경우)을 포함한 모든 중단지점을 나열합니다.

`tbreak``[([filename:]lineno | function) [, condition]]`

  한번 도달하면 제거되는 임시중단점입니다. 인자는 `break`과 동일합니다.

`cl(ear)``[filename:lineno | bpnumber [bpnumber ...]]`

  filename:lineno 인자가 주어진 경우, 해당 줄에 있는 모든 중단점을 제거합니다. 공백으로 구분된 중단점 번호 배열이 주어진 경우, 해당 중단점을 제거합니다. 인자가 없는 경우, 모든 중단지점을 재차 확인 후 제거합니다.

`disable``[bpnumber [bpnumber ...]]`

  공백으로 구분된 중단점 번호로 해당 중단점을 비활성화합니다. 중단점을 비활성화하는 것은 프로그램이 실행을 중단할 수 없다는 것입니다, 하지만 중단점을 제거하는 것과는 달리, 중단점 목록에 남아있으며 (재-)활성화할 수 있습니다.

`enable``[bpnumber [bpnumber ...]]`

  지정된 중단점을 활성화합니다.

`ignore` `bpnumber [count]`

  해당 중단점 번호를 무시할 횟수를 설정합니다. 만약 횟수가 생략된 경우, 무시 횟수는 0으로 설정됩니다. 무시 횟수가 0일 때 중단점이 활성화됩니다. 0이 아닐 때는, 중단점에 도달하고 중단점이 비활성화되지 않고 연관 조건이 참일 때마다 그 횟수가 차감됩니다.

`condition` `bpnumber [condition]`

  중단점에 새로운 condition을 설정합니다, 표현식이 참일 때만 중단점이 적용됩니다. 만약 condition이 없다면, 설정되어있던 모든 조건이 제거됩니다; 즉, 중단점에 적용되어있던 조건이 없어집니다.

`commands``[bpnumber]`

  중단점 번호 bpnumber 에 대한 명령을 지정합니다. 명령 목록은 다음 줄에 나타나게 됩니다. 명령을 종료하려면 `end`만 입력하면 됩니다. 예를 들면:

      (Pdb) commands 1
      (com) p some_variable
      (com) end
      (Pdb)

  중단점에 지정된 모든 명령을 제거하려면, `commands` 입력 후에 바로 `end`를 입력하면 됩니다; 즉, 아무 명령을 설정하지 않는 것입니다.

  bpnumber 인자가 주어지지 않으면, `commands`는 마지막 중단점 묶음을 참조하게 됩니다.

  중단점 명령을 활용해서 프로그램을 다시 시작할 수도 있습니다. `continue` 명령이나, `step` 또는 실행을 재개하는 다른 명령을 사용하기만 하면 됩니다.

  실행을 재개하는 아무 명령 (`continue`, `step`, `next`, `return`, `jump`, `quit` 및 해당 명령의 약어들)을 지정하는 것은 (`end` 명령을 붙인 것처럼) 해당 명령 목록을 끝내는 것입니다. 왜냐하면 실행을 재개할 때마다, 명령 목록을 가진 다른 중단점을 맞이할 수 있고, 어떤 목록을 실행해야 할지 모르는 상황이 생기기 때문입니다.

  만약 ‘slient’ 명령을 사용하면, 중단점에서 멈출 때 나오는 메시지는 출력되지 않습니다. 특정 메시지를 출력하고 진행되는 중단점에 바람직할 수 있습니다. 다만 그 어떤 명령도 출력하지 않는다면, 그 중단점에 도달했다는 것은 알 수 없습니다.

`s(tep)`

  현재 줄을 실행하고, 멈출 수 있는 가장 첫 번째 줄(호출되는 함수 또는 현재 함수의 다음 줄) 에서 멈춥니다.

`n(ext)`

  현재 함수의 다음 줄에 도달하거나, 반환할 때까지 계속 실행합니다. `next`와 `step`의 차이점은 `step`은 호출된 함수 안에서 멈추고, `next`는 호출된 함수를 재빠르게 실행하고 현재 함수의 바로 다음 줄에서만 멈춥니다.

`unt(il)``[lineno]`

  인자가 없는 경우에는, 현재 줄 번호보다 높은 줄 번호에 도달할 때까지 계속 실행합니다.

  줄 번호가 주어진 경우에는, 해당 번호보다 크거나 같은 줄에 도달할 때까지 계속 실행합니다. 두 경우 모두 현재 프레임이 반환될 때 멈춥니다.

  버전 3.2에서 변경: 줄 번호를 명시적으로 줄 수 있도록 허용합니다.

`r(eturn)`

  현재 함수가 반환될 때까지 계속 실행합니다.

`c(ont(inue))`

  중단점을 마주칠 때까지 계속 실행합니다.

`j(ump)``lineno`

  다음으로 실행될 줄을 설정할 수 있습니다. 프레임의 맨 마지막에서만 실행이 가능합니다. 이전 줄로 돌아가 코드를 재실행하거나, 실행을 원치 않는 코드를 건너뛸 수 있습니다.

  중요한 점은 이 명령은 언제나 실행할 수 있진 않습니다 – `for` 루프 내부로 들어가거나 `finally` 절을 건너뛰는 것은 불가능합니다.

`l(ist)``[first[, last]]`

  현재 파일의 소스 코드를 나열합니다. 인자가 없는 경우, 현재 줄 주위로 11줄을 나열하거나 이전 줄을 이어서 나열합니다. 인자로 `.`을 입력한 경우, 현재 줄 주위로 11줄을 나열합니다. 한 인자만 주어진 경우, 해당 줄 주위로 11줄을 나열합니다. 두 인자가 주어진 경우, 두 인자 사이의 모든 줄을 나열합니다; 만약 두 번째 인자가 첫 번째 인자보다 작은 경우, 첫 번째 인자로부터 나열하는 줄 수로 인식합니다.

  현재 프레임에서 현재 위치는 `->`로 표시됩니다. 예외를 디버깅할 때, 예외가 최초로 발생하거나 전파된 줄이 현재 줄과 다른 경우에는 `>>`로 표시됩니다.

  버전 3.2에 추가: `>>`표시

`ll``| longlist`

  현재 함수나 프레임의 소스 코드 전체를 나열합니다. 참고할만한 줄은 `list`처럼 표시됩니다.

  버전 3.2에 추가.

`a(rgs)`

  현재 함수의 인자 목록을 출력합니다.

`p` `expression`

  현재 컨텍스트에서 expression을 실행하고 값을 출력합니다.

  참고

  디버거 명령은 아니지만, `print()`도 사용될 수 있습니다 — 이때는 파이썬의 `print()` 함수를 실행하게 됩니다.

`pp` `expression`

  `p` 명령과 비슷하지만, 표현식의 값을 `pprint` 모듈을 활용하여 보기 좋은 형태로 출력합니다.

`whatis` `expression`

  expression의 형(type)을 출력합니다.

`source` `expression`

  주어진 객체의 소스 코드를 가져와서 보여줍니다.

  버전 3.2에 추가.

`display``[expression]`

  현재 프레임에서 실행이 중지될 때마다, 표현식의 값이 변경된 경우 표시합니다.

  표현식이 주어지지 않은 경우, 현재 프레임에서 표시되는 모든 표현식을 나열합니다.

  버전 3.2에 추가.

`undisplay``[expression]`

  현재 프레임에서 표현식을 더는 표시하지 않습니다. 표현식이 주어지지 않은 경우, 현재 프레임에서 표시되는 모든 표현식을 제거합니다.

  버전 3.2에 추가.

`interact`

  현재 스코프에서 찾을 수 있는 모든 지역 또는 전역 이름을 담고 있는 전역 이름 공간을 가진 (`code` 모듈을 활용하는) 대화형 인터프리터를 시작합니다.

  버전 3.2에 추가.

`alias``[name [command]]`

  command를 실행하는 name이라 불리는 에일리어스를 생성합니다. 명령은 따옴표로 감싸지 않아도 됩니다. 대체할 수 있는 파라미터는 `%1`, `%2` 등으로 표시되지만, `%*` 는 모든 파라미터로 대체됩니다. 만약 명령이 주어지지 않으면, 현재 name의 에일리어스가 표시됩니다. 만약 아무 인자가 주어지지 않으면, 모든 에일리어스가 나열됩니다.

  에일리어스는 중첩될 수 있고 pdb 프롬프트 내에서 정당하게 입력할 수 있는 모든 것을 담을 수 있습니다. 주의할 점은 pdb 내부 명령들이 에일리어스에 의해 오버라이드 될 수 있습니다. 그 명령은 에일리어스가 없어질 때까지 사용할 수 없게 됩니다. 에일리어싱은 명령 줄의 첫 번째 단어에 회귀적으로 적용됩니다; 나머지 단어들은 적용되지 않습니다.

  `.pdbrc`파일에 추가되면 특히 유용한 두 에일리어스 예시:

      # Print instance variables (usage "pi classInst")
      alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])
      # Print instance variables in self
      alias ps pi self

`unalias` `name`

  지정된 에일리어스를 제거합니다.

`!``statement`

  현재 스택 프레임의 컨텍스트에서 단일 statement를 실행합니다. 문장의 첫 단어가 디버거 명령이 아닌 경우, 느낌표는 제외해도 됩니다. 전역 변수를 설정하려면 실행하려는 명령과 동일한 줄 맨 앞에 `global`문장을 붙이면 됩니다, 예를 들면:

      (Pdb) global list_options; list_options = ['-l']
      (Pdb)

`run``[args ...]`
`restart``[args ...]`

  디버그 된 파이썬 프로그램을 재시작합니다. 만약 인자가 주어진 경우, `shlex`으로 나뉘게 되고 결과는 새 `sys.argv`로 사용됩니다. 이전 기록, 중단점, 행동 그리고 디버거 옵션은 유지됩니다. `restart`는 `run`의 에일리어스입니다.

`q(uit)`

  디버거를 종료합니다. 실행되고 있는 프로그램이 종료됩니다.

`debug` `code`

  code 인자(현재 환경에서 실행될 임의의 표현식이나 문장)를 단계별로 수행하는 재귀적 디버거에 진입합니다.

`retval`

  함수의 마지막 반환에 대한 반환 값을 인쇄합니다.

각주

1

  프레임이 특정 모듈에서 시작되는 것으로 간주하는지 여부는 프레임 전역에 있는 `__name__`에 의해 결정됩니다.