bdb — 디버거 프레임워크
bdb — 디버거 프레임워크 (Debugger framework)
브레이크포인트 설정이나 디버거를 통한 실행 관리 같은 기본 디버거 기능을 처리하는 모듈이에요.
출처: Python 표준 라이브러리
본문
bdb 모듈은 브레이크포인트 설정이나 디버거를 통한 실행 관리 같은 기본 디버거 기능을 처리해요.
다음 예외가 정의돼요:
exception bdb.BdbQuit
디버거를 종료하기 위해 Bdb 클래스가 발생시키는 예외예요.
bdb 모듈은 또한 두 클래스를 정의해요.
class bdb.Breakpoint(self, file, line, temporary=False, cond=None, funcname=None)
이 클래스는 임시 브레이크포인트, 무시 횟수(ignore count), 비활성화와 (재)활성화, 조건부를 구현해요.
브레이크포인트는 bpbynumber라는 리스트를 통해 번호로, bplist를 통해 (file, line) 쌍으로 인덱싱돼요. 전자는 Breakpoint 클래스의 단일 인스턴스를 가리키고, 후자는 한 줄에 브레이크포인트가 두 개 이상 있을 수 있으므로 해당 인스턴스들의 리스트를 가리켜요.
브레이크포인트를 만들 때 연결된 파일 이름은 표준(canonical) 형태여야 해요. funcname이 정의되면 함수의 첫 줄이 실행될 때 브레이크포인트 히트가 카운트돼요. 조건부 브레이크포인트는 항상 히트를 카운트해요.
Breakpoint 인스턴스 메서드:
deleteMe()— 파일/줄에 연결된 리스트에서 브레이크포인트를 삭제해요. 그 위치의 마지막 브레이크포인트라면 파일/줄 항목도 삭제해요.enable()— 브레이크포인트를 활성화된 것으로 표시해요.disable()— 브레이크포인트를 비활성화된 것으로 표시해요.bpformat()— 브레이크포인트에 대한 모든 정보를 깔끔하게 포맷한 문자열을 반환해요: 브레이크포인트 번호, 임시 상태(del 또는 keep), 파일/줄 위치, 중단 조건, 무시할 횟수, 히트된 횟수. 3.2 버전에서 추가.bpprint(out=None)—bpformat()의 출력을 파일out에, 또는None이면 표준 출력에 인쇄해요.
Breakpoint 인스턴스 속성:
file— 브레이크포인트의 파일 이름.line—file안에서 브레이크포인트의 줄 번호.temporary—(file, line)의 브레이크포인트가 임시면True.cond—(file, line)의 브레이크포인트를 평가하기 위한 조건.funcname— 함수에 진입할 때 브레이크포인트가 히트되는지 여부를 정의하는 함수 이름.enabled— 브레이크포인트가 활성화면True.bpbynumber—Breakpoint단일 인스턴스의 숫자 인덱스.bplist—(file, line)튜플로 인덱싱된Breakpoint인스턴스의 사전.ignore— 브레이크포인트를 무시할 횟수.hits— 브레이크포인트가 히트된 횟수 카운트.
class bdb.Bdb(skip=None, backend='settrace')
Bdb 클래스는 일반적인 Python 디버거 베이스 클래스로 동작해요. 이 클래스는 trace 기능의 세부사항을 처리하고, 파생 클래스는 사용자 상호작용을 구현해야 해요. 표준 디버거 클래스(pdb.Pdb)가 그 예시예요.
skip 인자는 주어지면 glob 스타일 모듈 이름 패턴의 iterable이어야 해요. 디버거는 이 패턴 중 하나와 일치하는 모듈에서 시작된 프레임으로는 들어가지 않아요. 프레임이 특정 모듈에서 시작된 것으로 간주되는지는 프레임 globals의 __name__으로 결정돼요.
backend 인자는 Bdb에 사용할 백엔드를 지정해요. 'settrace' 또는 'monitoring'이 될 수 있어요. 'settrace'는 최고의 하위 호환성을 가진 sys.settrace()를 사용해요. 'monitoring' 백엔드는 Python 3.12에서 도입된 새 sys.monitoring을 사용하는데, 사용하지 않는 이벤트를 비활성화할 수 있으므로 훨씬 효율적일 수 있어요. 두 백엔드에 대해 정확한 인터페이스를 유지하려고 노력하고 있지만 몇 가지 차이가 있어요. 디버거 개발자는 더 나은 성능을 위해 'monitoring' 백엔드를 사용하는 것이 권장돼요.
3.1 버전 변경:
skip매개변수 추가.3.14 버전 변경:
backend매개변수 추가.
보통 오버라이드할 필요가 없는 Bdb 메서드:
-
canonic(filename)—filename의 표준 형태를 반환해요. 실제 파일 이름의 표준 형태는 운영체제에 의존적이고 대소문자가 정규화된 절대 경로예요. 인터랙티브 모드에서 생성된stdin같은 꺾쇠괄호가 있는 파일 이름은 변경 없이 반환돼요. -
start_trace(self)— 추적을 시작해요.'settrace'백엔드의 경우 이 메서드는sys.settrace(self.trace_dispatch)와 동일해요. 3.14 버전에서 추가. -
stop_trace(self)— 추적을 중지해요.'settrace'백엔드의 경우sys.settrace(None)과 동일해요. 3.14 버전에서 추가. -
reset()—botframe,stopframe,returnframe,quitting속성을 디버깅을 시작할 준비가 된 값으로 설정해요. -
trace_dispatch(frame, event, arg)— 디버깅되는 프레임의 trace 함수로 설치되는 함수예요. 반환값은 새 trace 함수예요(대부분의 경우 그 자체). 기본 구현은 실행될 이벤트의 유형(문자열로 전달)에 따라 프레임을 어떻게 디스패치할지 결정해요.event는 다음 중 하나일 수 있어요:line— 새 코드 줄이 실행되려고 함.call— 함수가 호출되거나 다른 코드 블록에 진입하려고 함.return— 함수나 다른 코드 블록이 반환하려고 함.exception— 예외가 발생함.c_call— C 함수가 호출되려고 함.c_return— C 함수가 반환함.c_exception— C 함수가 예외를 발생시킴.
Python 이벤트에 대해서는 전문화된 함수(아래 참고)가 호출돼요. C 이벤트에 대해서는 아무 조치가 취해지지 않아요.
arg매개변수는 이전 이벤트에 따라 달라져요. trace 함수에 대한 자세한 내용은sys.settrace()문서를, code와 frame 객체에 대한 자세한 내용은 표준 타입 계층(The standard type hierarchy)을 참고하세요. -
dispatch_line(frame)— 디버거가 현재 줄에서 멈춰야 하면user_line()메서드(서브클래스에서 오버라이드해야 함)를 호출해요.quitting플래그가 설정돼 있으면(user_line()에서 설정 가능)BdbQuit예외를 발생시켜요. 그 범위에서 추가 추적을 위해trace_dispatch()메서드 참조를 반환해요. -
dispatch_call(frame, arg)— 디버거가 이 함수 호출에서 멈춰야 하면user_call()메서드를 호출해요.quitting이 설정돼 있으면BdbQuit을 발생시켜요.trace_dispatch()참조를 반환해요. -
dispatch_return(frame, arg)— 디버거가 이 함수 반환에서 멈춰야 하면user_return()메서드를 호출해요.quitting이 설정돼 있으면BdbQuit을 발생시켜요.trace_dispatch()참조를 반환해요. -
dispatch_exception(frame, arg)— 디버거가 이 예외에서 멈춰야 하면user_exception()메서드를 호출해요.quitting이 설정돼 있으면BdbQuit을 발생시켜요.trace_dispatch()참조를 반환해요.
보통 파생 클래스가 오버라이드하지 않지만, 멈춤과 브레이크포인트의 정의를 재정의하려면 오버라이드할 수 있는 메서드:
is_skipped_module(module_name)—module_name이 어떤 skip 패턴과도 일치하면True를 반환해요.stop_here(frame)—frame이 스택에서 시작 프레임 아래에 있으면True를 반환해요.break_here(frame)— 이 줄에 유효한 브레이크포인트가 있으면True를 반환해요. 줄 또는 함수 브레이크포인트가 존재하고 유효한지 확인해요.effective()의 정보에 기반해 임시 브레이크포인트를 삭제해요.break_anywhere(frame)—frame의 파일 이름에 어떤 브레이크포인트가 존재하면True를 반환해요.
파생 클래스가 디버거 동작 제어를 위해 오버라이드해야 하는 메서드:
user_call(frame, argument_list)— 중단이 호출된 함수 안에서 멈출 수 있으면dispatch_call()에서 호출돼요.argument_list는 더 이상 사용되지 않으며 항상None이에요. 이 인자는 하위 호환성을 위해 유지돼요.user_line(frame)—stop_here()또는break_here()가True를 반환할 때dispatch_line()에서 호출돼요.user_return(frame, return_value)—stop_here()가True를 반환할 때dispatch_return()에서 호출돼요.user_exception(frame, exc_info)—stop_here()가True를 반환할 때dispatch_exception()에서 호출돼요.do_clear(arg)— 브레이크포인트가 임시일 때 어떻게 제거해야 하는지 처리해요. 이 메서드는 파생 클래스가 구현해야 해요.
파생 클래스와 클라이언트가 스테핑 상태에 영향을 주기 위해 호출할 수 있는 메서드:
set_step()— 한 줄의 코드 후에 멈춰요.set_next(frame)— 주어진 프레임 안이나 아래의 다음 줄에서 멈춰요.set_return(frame)— 주어진 프레임에서 반환할 때 멈춰요.set_until(frame, lineno=None)— 현재 것보다 큰lineno를 가진 줄에 도달하거나 현재 프레임에서 반환할 때 멈춰요.set_trace([frame])—frame에서 디버깅을 시작해요.frame을 지정하지 않으면 호출자의 프레임에서 시작해요. 3.13 버전 변경:set_trace()는 실행될 다음 코드 줄이 아니라 즉시 디버거에 진입해요.set_continue()— 브레이크포인트에서만 멈추거나 완료됐을 때 멈춰요. 브레이크포인트가 없으면 시스템 trace 함수를None으로 설정해요.set_quit()—quitting속성을True로 설정해요. 이는 다음dispatch_*()메서드 호출에서BdbQuit을 발생시켜요.
파생 클래스와 클라이언트가 브레이크포인트를 조작하기 위해 호출할 수 있는 메서드. 뭔가 잘못되면 오류 메시지 문자열을, 잘 되면 None을 반환해요:
set_break(filename, lineno, temporary=False, cond=None, funcname=None)— 새 브레이크포인트를 설정해요. 인자로 전달된filename에 대해lineno줄이 존재하지 않으면 오류 메시지를 반환해요.filename은canonic()메서드에 설명된 대로 표준 형태여야 해요.clear_break(filename, lineno)—filename과lineno의 브레이크포인트를 삭제해요. 설정된 게 없으면 오류 메시지를 반환해요.clear_bpbynumber(arg)—Breakpoint.bpbynumber에서 인덱스arg를 가진 브레이크포인트를 삭제해요.arg가 숫자가 아니거나 범위를 벗어나면 오류 메시지를 반환해요.clear_all_file_breaks(filename)—filename의 모든 브레이크포인트를 삭제해요. 설정된 게 없으면 오류 메시지를 반환해요.clear_all_breaks()— 모든 기존 브레이크포인트를 삭제해요. 설정된 게 없으면 오류 메시지를 반환해요.get_bpbynumber(arg)— 주어진 번호로 지정된 브레이크포인트를 반환해요.arg가 문자열이면 숫자로 변환돼요.arg가 숫자가 아닌 문자열이거나, 주어진 브레이크포인트가 존재한 적이 없거나 삭제됐으면ValueError가 발생해요. 3.2 버전에서 추가.get_break(filename, lineno)—filename의lineno에 브레이크포인트가 있으면True를 반환해요.get_breaks(filename, lineno)—filename의lineno에 대한 모든 브레이크포인트를 반환하거나, 설정된 게 없으면 빈 리스트를 반환해요.get_file_breaks(filename)—filename의 모든 브레이크포인트를 반환하거나, 설정된 게 없으면 빈 리스트를 반환해요.get_all_breaks()— 설정된 모든 브레이크포인트를 반환해요.
파생 클래스와 클라이언트가 더 나은 성능을 위해 이벤트를 비활성화하고 재시작하는 데 호출할 수 있는 메서드. 'monitoring' 백엔드에서만 동작해요:
disable_current_event()— 다음에restart_events()가 호출될 때까지 현재 이벤트를 비활성화해요. 디버거가 현재 줄에 관심이 없을 때 도움이 돼요. 3.14 버전에서 추가.restart_events()— 비활성화된 모든 이벤트를 재시작해요. 이 함수는user_*메서드가 호출된 후dispatch_*메서드에서 자동으로 호출돼요.dispatch_*메서드를 오버라이드하지 않으면 비활성화된 이벤트는 매 사용자 상호작용 후 재시작돼요. 3.14 버전에서 추가.
스택 트레이스를 나타내는 데이터 구조를 얻기 위해 호출할 수 있는 메서드:
get_stack(f, t)— 스택 트레이스의(frame, lineno)튜플 리스트와 크기를 반환해요. 가장 최근에 호출된 프레임이 리스트의 마지막이에요.size는 디버거가 호출된 프레임 아래에 있는 프레임의 수예요.format_stack_entry(frame_lineno, lprefix=': ')—(frame, lineno)튜플인 스택 항목에 대한 정보가 담긴 문자열을 반환해요. 반환 문자열에는 표준(캐노니컬) 파일 이름, 함수 이름 또는 lambda, 입력 인자, 반환값, 코드 줄(존재한다면)이 포함돼요.
클라이언트가 문자열로 주어진 명령문을 디버깅하기 위해 호출할 수 있는 두 메서드:
run(cmd, globals=None, locals=None)—exec()함수를 통해 실행되는 명령문을 디버깅해요.globals는 기본적으로__main__.__dict__이고,locals는 기본적으로globals예요.runeval(expr, globals=None, locals=None)—eval()함수를 통해 실행되는 표현식을 디버깅해요.globals와locals는run()과 같은 의미예요.runctx(cmd, globals, locals)— 하위 호환성을 위한 것.run()메서드를 호출해요.runcall(func, /, *args, **kwds)— 단일 함수 호출을 디버깅하고 그 결과를 반환해요.
마지막으로 모듈은 다음 함수를 정의해요:
bdb.checkfuncname(b, frame)
여기서 멈춰야 하는지 여부를 Breakpoint b가 설정된 방식에 따라 True를 반환해요. 줄 번호로 설정됐으면 b.line이 frame의 것과 같은지 확인해요. 함수 이름으로 설정됐으면 올바른 프레임(올바른 함수)에 있고 첫 번째 실행 가능한 줄에 있는지 확인해야 해요.
bdb.effective(file, line, frame)
(active breakpoint, delete temporary flag) 또는 (None, None)을 작용할 브레이크포인트로 반환해요. 활성 브레이크포인트는 (file, line)(존재해야 함)에 대한 bplist의 첫 항목으로, 활성화되어 있고 checkfuncname()이 참이며 조건이 거짓이 아니고 무시 횟수가 양수가 아닌 것이에요. 임시 브레이크포인트가 삭제되어야 한다는 뜻의 플래그는 cond를 평가할 수 없을 때만 False예요(이 경우 무시 횟수는 무시돼요). 그런 항목이 없으면 (None, None)이 반환돼요.
bdb.set_trace()
호출자의 프레임에서 Bdb 인스턴스로 디버깅을 시작해요.