브레이크포인트
브레이크포인트(breakpoint), 중단점, 중지점은 소프트웨어 개발에서 프로그램을 의도적으로 잠시 또는 아예 멈추게 하는 장소를 가리키며 디버깅 목적으로 넣는 것이다.
브레이크포인트는 이미 실행중인 프로그램에 대한 정보를 알아내기 위한 수단으로 사용되며, 이를 이용해 프로그램 실행이 중단되어있는 상황에서 프로그래머는 각종 테스트 환경 (일반 목적의 레지스터, 메모리, 로그, 파일 등)을 점검하여 프로그램이 예측한대로 기능하고 있는지, 그렇지 않을 경우 문제점이 무엇인지 알아낸다. 따라서 브레이크포인트는 원하는 순간에 프로그램 실행을 중단하기 위한 조건을 함께 가질 수 있다.
브레이크포인트 조건
편집브레이크포인트들은 주로 실행중인 원래 명령어가 실행되기 전에 프로그램을 일시적으로 인터럽트하기 위해 사용된다. 이것은 종종 명령어 브레이크포인트로 불린다. 또한 메모리의 특정한 읽기나 쓰기, 수정 같은 다른 종류의 조건들도 사용될 수 있다. 이것은 종종 조건부 브레이크포인트나 데이터 브레이크포인트 등으로 불린다. 그 외에도 특정한 시간에 인터럽트를 실행시키기 위해 사용될 수 있다.
조사 툴
편집브레이크포인트가 발생하면, 프로그램의 상태를 조사하거나 이것을 바꾸는 많은 툴들이 사용된다. 각 스레드의 스택 추적은 정지된 명령어에 이르게 하는 함수 호출들의 체인을 보기 위해 사용될 수 있다. watches의 리스트는 선택된 변수들과 식값들을 볼 수 있게 한다. 또한 프로그램 모듈들과 다른 정보들이 로드된 레지스터들의 내용을 볼 수 있는 툴들도 있다.
구현
편집하드웨어
편집많은 프로세서들은 브레이크포인트들을 위한 하드웨어 지원을 포함한다. 예를 들면, x86 명령어 집합 아키텍처는 x86 디버그 레지스터를 통해 하드웨어 지원을 제공한다. 이러한 하드웨어는 한계를 갖는데, 예를 들면 브랜치 지연 슬롯에 위치한 명령어에 브레이크포인트를 걸 수 없다는게 있다. 이런 종류의 한계는 프로세서의 마이크로아키텍처에 의해 강제되며, 프로세스마다 다르다.
소프트웨어
편집하드웨어의 지원 없이는 (그리고 멀티태스킹 환경에서는), 디버거는 소프트웨어를 통해 브레이크포인트를 구현해야 한다. 브레이크포인트 명령어를 위해서 그 위치의 명령어를 아래와 같은 명령어로 바꾸는 것은 상대적으로 간단한 일이다.
- 디버거를 직접적으로 호출하는 명령어(예를 들면 시스템 호출) 또는
- 고의적인 프로그램 인터럽트를 일으키는 유효하지 않은 명령어(그 후에 가로채져서 디버거에 의해 관리된다.)
이 기술은 공유 프로그램 저장소를 사용하는 멀티태스킹 시스템에서 구현되기 어려울 수도 있다(인터럽트가 다른 스레드에서 발생하므로 스레드를 위한 원래 명령어의 회복이 요구된다). 또한 프로그램이 보호중인 메모리에 위치한다면 명령어를 겹쳐쓰는 것이 거부될 수 있다.
대신,
- 명령어 집합 시뮬레이터는 자신의 평범한 프로그램 사이클 안에 적절한 조건 테스트를 삽입함으로써 조건부 또는 무조건적인 브레이크포인트를 단순하게 구현할 수 있다.[2]
- 인터프리트 언어는 위와 같이, 자신의 프로그램 사이클 안에서 효과적으로 같은 개념을 사용할 수 있다.
- 그러나 추가적인 소스 코드 서술(내부 또는 외부 서브루틴을 발생시키는 함수를 만들어내는)을 통해서 소스 코드를 인스트루먼테이션하는 것은 또 다른 흔한 접근법이다. 이 방식은 바이너리의 크기를 증가시키고, 보통의 메모리 할당과 예외 처리에 악영향을 줄 수 있다. 몇몇 컴파일러들의 "디버그" 옵션들은 이 기술을 반투명하게 구현한 것이다.
몇몇 디버거들은 레지스터들이나 메모리의 프로그램 변수들이 재개하기 전에 수정되는 것을 허용하며, 효과적으로 (테스트를 목적으로 임시적으로 할당된) 수작업된 코드들을 도입하는 것을 허용한다. 비슷하게, 프로그램 명령어들은 프로그램 로직의 변화에 의한 효과를 알아내기 위해 종종 건너띄어 진다. 많은 경우 이것은 모호한 "이벤트 구동형" 에러 서브루틴들을 테스트하기 위한 단 하나의 방법이다. 중지된 프로그램의 재개 위치를 직접 바꾸는 것은 특정한 하드웨어 조건 핸들러같이 코드의 거의 실행되지 않는 섹션에 들어갈 목적으로 사용된다.
그러나 소프트웨어에 데이터 브레이크포인트를 구현하는 것은 디버깅되는 응용 프로그램의 성능을 굉장히 낮출 수 있다. 왜냐하면 이것은 같은 프로세서의 추가적인 자원을 요구하기 때문이다.[3] 그러나 이것은 보통 테스트의 경우나 사용 가능한 정보의 양이 디버거의 한계로 제한되지 않을 경우에는 받아들여질 수 있다. 예를 들면 소프트웨어 구현은 (특정한 하드웨어 플랫폼에 의해서 무엇이 저장될 것인지같은 논거를 위해) 프로그램/서브루틴/명령어 레벨에서 논리적 경로 데이터를 모을 수 있다. 명령어 집합 시뮬레이션 방법은 명령어 교체 방식이 비해 과부하를 굉장히 줄여줄 뿐만 아니라 캐시 미스도 줄여준다.
몇몇 프로그래밍 언어 구현들은 다른 프로그램들에서 사용되는 그들의 디버깅 함수들을 반영한다. 예를 들면, 몇몇 포트란 방언들은 원래 명령어 브레이크포인트처럼 행동하게 의도된 AT 구문을 갖는다. 파이썬은 파이썬 프로그램에서 접근할 수 있는 디버거를 구현한다.[4] 이러한 기능들은 COMEFROM 구문처럼 행동하는 방식으로 남용될 수 있다.[5]
같이 보기
편집각주
편집- ↑ Abbate, Janet (2012), 《Recoding Gender: Women's Changing Participation in Computing》, MIT Press, 32쪽, ISBN 9780262018067
- ↑ IBM OLIVER (CICS interactive test/debug)
- ↑ “GDB Internals”. 2011년 11월 29일에 원본 문서에서 보존된 문서. 2015년 10월 12일에 확인함.
- ↑ “Python Library Reference: The Python Debugger”. 2008년 9월 13일에 원본 문서에서 보존된 문서. 2014년 8월 20일에 확인함.
- ↑ entrian.com - goto and comefrom for Python