동의어
Python에서는 tracback (역추적) 이라는 용어가 많이 사용되지만,
stack trace 또는 back trace라고도 불린다.
의미
Python의 실행 등에서 에러가 발생할 경우 출력되는 traceback 은
- 해당 에러가 발생한 지점에서의 stack 의 정보를
- 역추적(back-trace)하여 출력한 결과물을 의미한다.
stack에는
에러가 발생하여 프로그램 수행이 멈춘 특정 지점이
수행되기까지 관련되어 수행된
모든 function calls에 관련된 정보들이 담겨져 있다.
stack 은
프로그램 코드에서 function call에서 이용되는 데이터 구조를 의미하며,
동시에 virtual memory 구조에서 상위에 위치한 영역을 가르키기도 하는 용어이다.
보다 자세한 건 다음 URL을 확인할 것.
https://dsaint31.me/mkdocs_site/CE/ch05/ch05_02_01_function/#function-call-stack
https://dsaint31.tistory.com/506
Debugging 시 읽는 방법.
일반적으로 Traceback의 메시지를 통해 debugging을 할 때에는 밑에서부터 읽어 올라가야 한다.
- back 라는 용어가 가르키듯이 역으로 stack의 정보들을 추적하기 때문에
- 맨 아래에 에러가 발생한 지점에 대한 정보가 있고,
- 위로 올라갈 수록 해당 지점의 코드가 수행되기 위해 실행된 function call 들의 정보가 담겨 있기 때문이다.
그리고, Traceback의 메시지에서 출력된 정보들 중, 관련 파일명을 살펴서 본인이 작성한 파일에 해당하는 정보부터 확인 해나가야 한다.
- Traceback의 메시지에는 에러 발생한 지점이 수행되기까지 호출이 이루어진 모든 functions들의 정보가 있기 때문에
- Python의 표준 라이브러리나 사용한 Thirdparty library의 functions들의 호출정보도 출력된다.
- 이들 파일에 대해서는 디버깅에서 수정을 하지 못하므로 결국 본인이 작성한 파일에 해당하는 메시지를 골라서 디버깅해야 한다.
Traceback (most recent call last):
File "/Users/dsaint31/Desktop/lectures/python/debug/ds_traceback.py", line 15, in ds_main
ret_v = ds_div(float(numerator_str), float(denominator_str))
ValueError: could not convert string to float: 'as'
traceback 모듈
try
- except
문을 통해, 특정 예외가 발생해도 Python 프로그램이 종료하지 않게 처리한 경우에도,
traceback
모듈을 사용하여 해당 예외가 발생과 관련된 traceback 정보를 얻을 수 있음.
- 이 경우, 프로그램 수행이 중단되지 않으면서도 에러와 관련된 traceback 정보를 얻을 수 있다.
Thread
를 이용하여 별도의 task를 수행하는 경우 (e.g. Qt에서 QRunnable 등을 상속한 worker)에 발생하는 예외 등을 처리할 때 traceback 모듈을 많이 사용한다.
주로 사용되는 함수
print_exc()
: traceback 메시지를 출력한다.format_exc()
: traceback 메시지 에 해당하는 문자열을 반환한다.
이외에도 현재 발생한 예외(or 에러)에 대한 정보를 담고 있는 tuple
을 반환하는 sys.exc_info()
도 많이 사용된다.
반환하는 tuple
은 다음과 같은 세 개의 item으로 구성됨.
error type
: 예외의 종류. :type(e)
exceptions.ZeroDivisionError
와 같은 발생한 에러를 추상화하고 있는 class type을 알려줌.
error value
: 예외에 대한 일종의 설명이 놓임. :e
traceback
: 발생한 예외에 해당하는traceback
객체(object) 가 담김.:e.__traceback__
- 보통 print 로 출력시 해당 예외의 traceback 메시지들이 출력됨.
- 해당 traceback object 에 대한 참고문서 : Traceback objects
Example code
import traceback
import sys
def ds_div(numerator, denominator):
tmp = numerator / denominator
return tmp
def ds_main():
try:
numerator_str = input('enter numerator:')
denominator_str = input('enter denominator:')
ret_v = ds_div(float(numerator_str), float(denominator_str))
print(f'{numerator_str}/{denominator_str} = {ret_v}')
except:
traceback.print_exc()
print('----------------------')
e_type, e_value, tb = sys.exc_info()
print(f'{e_type} / {e_value} / {tb}')
print(f'{type(tb)}')
if __name__ == '__main__':
ds_main()
- 입력값에서 분모를 0으로 할 경우나, 숫자로 바뀌지않는 문자열을 넣으면 예외가 발생함.
- 이들 예외가 발생할 경우, 출력을 보면 위의 메서드들의 활용법을 이해할 수 있음.
References
https://docs.python.org/ko/3.10/library/traceback.html#module-traceback
https://docs.python.org/ko/3/library/sys.html#sys.exc_info
'Python' 카테고리의 다른 글
[pandas] Column (or rows) 제거하기 (0) | 2024.01.09 |
---|---|
[Term] Agile Programming Language : Agile Development (=Programming) (0) | 2024.01.06 |
[Python] logging (0) | 2023.12.18 |
[Python] Terminal, WSL, Conda, and VSCode (1) | 2023.12.15 |
[Etc] Token and Tokenizer (2) | 2023.12.06 |