2011년 6월 8일 수요일

파이썬 3.3에 새로 추가된 faulthandler 모듈은 디버깅을 도와줍니다

원문: New faulthandler module in Python 3.3 helps debugging (날짜: 2011-05-12, 작성자: Victor Stinner)

여러분의 프로그램 사용자가 프로그램이 죽거나 멈춘다고 보고해 온다면 여러분이 할 수 있는 일은 그 사용자가 더 많은 정보를 모을 수 있도록 하거나 그 상황을 재현할 수 있는 시나리오를 만들어 내도록 돕는 것 뿐입니다. 사용자의 확실한 시나리오라 할지라도 환경이 서로 달라서(예를 들자면 운영 체제나 컴파일러) 개발자가 그 상황을 재현하지 못하기도 합니다. 운이 좋은 경우는 사용자가 디버깅 도구를 설치하기도 하지만, 대부분은 같은 상황에 대해 다른 누군가가 더 많은 정보를 얻어줄 때까지 기다려야만 할 것입니다.

심각한 오류

파이썬 3.3에서 새로 추가된 faulthandler 모듈이 이런 문제에 도움이 됩니다. faulthandler는 세그멘테이션 폴트, 0으로 나눔, 어보트(abort), 버스 오류와 같은 심각한 오류 상황에서 파이썬 트레이스백(traceback)을 기록해주는 기능을 제공합니다. 이 기능은 프로그램에서 faulthandler.enable()를 사용하거나 파이썬 실행 파일에 -X faulthandler 옵션을 주거나 환경 변수를 PYTHONFAULTHANDLER=1로 설정하여 활성화할 수 있습니다. 출력의 예:

Fatal Python error: Segmentation fault

Current thread 0x00007f7babc6b700:
  File "Lib/test/crashers/gc_inspection.py", line 29 in g
  File "Lib/test/crashers/gc_inspection.py", line 32 in <module>
Segmentation fault

타임아웃

faulthandler는 또한 faulthandler.dump_tracebacks_later(timeout)를 사용하면 주어진 타임아웃 후에 트레이스백을 기록해줍니다. 이 함수를 다시 호출하면 타이머는 재시작되며, faulthandler.cancel_dump_tracebacks_later()를 호출하면 타이머는 중단됩니다. 출력의 예:

Timeout (0:01:00)!
Current thread 0x00007f987d459700:
  File "Lib/test/crashers/infinite_loop_re.py", line 20 in <module>

repeat=True 옵션을 사용하면 매 timeout 초마다 기록해줍니다. exit=True를 사용하면 안전하지 않은 방식으로(예를 들면 파일을 플러시하지 않음) 바로 프로그램을 종료시킵니다.

사용자 시그널

프로그램이 실행 중인 호스트에 접근할 수 있다면 faulthandler.register(signal)를 사용하여 signal을 받았을 때 트레이스백을 기록하도록 시그널 핸들러를 설치해 둘 수 있습니다. 예를 들면, UNIX에서는 SIGUSR1 시그널을 활용할 수 있습니다. kill -USR1 <pid>로 현재 트레이스백을 기록할 수 있을 것입니다. 이 기능은 Windows에서는 사용할 수 없습니다. 출력의 예:

Current thread 0x00007fdc3da74700:
  File "Lib/test/crashers/infinite_loop_re.py", line 19 in <module>

다른 사용법으로 프로그램에서 직접 faulthandler.dump_traceback()를 호출하는 것도 가능합니다.

보안 문제와 출력 파일

보안상의 이유로 기본적으로 faulthandler는 비활성화 되어 있습니다. 주된 이유는 sys.stderr의 파일 디스크립터를 저장했다가 그 파일 디스크립터로 트레이스백을 기록하기 때문입니다. 만약 sys.stderr가 닫힌 후 그 파일 디스크립터가 재사용 된다면 그 파일 디스크립터는 소켓, 파이프, 중요한 파일, 또는 다른 어떤 것이 될 수 있습니다. 기본적으로 faulthandler는 트레이스백을 sys.stderr에 기록하지만 다른 파일을 지정할 수 있습니다. 자세한 내용은 faulthandler 문서를 참고하시기 바랍니다.

예전 파이썬 버전을 위한 외부 모듈

faulthandler는 파이썬 2.5에서 3.2를 위해 PyPI에 외부 모듈로도 유지 보수되고 있습니다. 파이썬 3.3의 모듈과 이 외부 모듈의 가장 큰 차이는 dump_tracebacks_later()의 구현에 있습니다. 파이썬 3.3은 잠금에 타임아웃을 주어 쓰레드를 사용하는 반면 외부 모듈은 SIGALRMalarm()을 사용합니다.

잠금 타임아웃은 파이썬 3.3의 새로운 기능으로 마이크로초 단위의 정밀도를 갖습니다. 예전 버전에서 사용되는 alarm() 타이머는 1초의 정밀도를 갖으며 SIGALRM 시그널은 실행 중인 시스템 호출을 EINTR 오류를 내면서 실패하도록 하여 중단시킬 수 있습니다.

초기 성공 사례

새로 추가된 faulthandler 모듈은 이미 우리의 빌드봇(buildbot)에서 경쟁 조건을 추적하는데 도움을 주었습니다. 이 모듈이 여러분의 프로그램에서도 도움이 되기를 희망합니다.

댓글 없음:

댓글 쓰기