03. 코딩하는 동안에 디버깅하기
Assertion 함수나 매크로로 디버그 빌드에서만 실행된다. 어떤 조건이 실패했는지 알려주는 역활을 한다. 또한 어떤 변수나 프로그램의 상태는 변경하지 않는다.(읽기전용)
Assertion Role
1. 한번에 하나씩 확인하는 것
2. 그 값이 가져야할 값을 명확히 확인하기
무엇을 assertion할 것인가?
1. 함수에 들어오는 매개변수, 모든 함수에서 매개변수 확인은 문제가 될 수 있다. 그렇다면 문제 발생시마다 assertion을 추가하는 것도 좋다.
2. 반환 값. 반환값들을 assertion하면 문제가 생기는 때를 확인할 수 있다.
3. 세운 가정 확인 시. 일반적인 함수/매크로로 가정을 모두 확인 할 수는 없다. 조건적 컴파일을 이용해야 하는데 함수를 이용한다.
VERIFY 매크로
MFC 디버깅모드에서 사용가능하며, 조건이 0으로 평가되면, assertion 메시지 상자를 나타내서 경고한다. 하지만 릴리즈 모드에서는 assertion과 다르게 매개변수는 소스코드에 머물러 정상적인 부분으로 평가된다.
VERIFY가 좋은 경우는 별도로 확인하지 않게 되는 오류값을 반환하는 함수가 있는 경우, CString::LoadString()은 리소스 스트링을 로드하는데, 실패시 VERIFY가 경고를 해준다. ASSERT도 같은 결과를 얻을 수 있지만 사용되는 변수 생성 부담을 덜 수 있다.
assert, _ASSERT, _ASSERTE
assert : c Runtime Lib에서 사용. ASSERT.H로 include, assert에서 실패시 stderr로 보낸다.
파일 이름이 60개로 한정, UI를 가지지 않은 프로젝트에서는 문제가 생길 수 있다.
_ASSERT, _ASSERTE(표현식을 매개변수로 표시)는 CRTDBG.H에 정의되어있다.
C 런타임 구현 매크로가 assertion을 파일로 보내게 하여 디폴트로 메시지 상자로 보내거나 _CrtSetReportMode 함수를 호출하여 OutputDebugString API 함수로 보내는 것을 정할 수 있다. 모든 assertion들은 하나의 문제가 있는데, 시스템의 상태를 변경하느 ㄴ것이다.
ASSERT_KINDOF, ASSERT_VALID (mfc 전용)
ASSERT_KINDOF : CObject에서 나온 클래스를 가리키는 포인터가 특정 클래스인지 확인.
ASSERT_VALID : CObject에서 온 클래스를 가리키는 포인터인지 아닌지 검증
SUPERASSERT
[링크] SUPERASSERT.h / SUPERASSERT.cpp
[사용예]BugSlayer를 설치하고 BUGSLAYERUTIL.H와 BUGSLAYERUTIL.LIB 사용
SUPERASSERT를 이용해서 ASSERT와 assertion호출들을 함수들로 자동 돌린다. 또한 매크로나 함수를 이용하면, 자동으로 스택 트레이스를 가지게 된다.
많은 트레이스문 사용하기
TRACE printf스타일의 디버깅으로 유용하다.
단점은, 트레이스문 호출시, 연속으로 트레이스문 사용하여 스레드의 순서가 바뀔 수 있다.
또한 serialization문제로 많은 트레이스문들이 디버그 빌드를 느리게 한다.
트레이스문은 디버거 윈도우에서만 보는데, DebugView로 디버거 밖에서도 트레이스문을 볼 수 있다.
주석 많이 넣기
- 각각의 함수나 메소드들은 정보를 명확하게 할 수 있는 문장을 사용
-> 루틴이 무엇을 하는가? 각각의 입력 매개변수는 어떤 것을 포함하는가? 성공과 실패에 대한 출력 매개변수?, 가능한 반환 값은 각각 무엇인가?
- 중요한 알고리즘에 대한 완전한 설명
- 코드에서 고쳐지지 않은 사소한 버그는 버그 내용과 고친 내용을 주석으로 설명
- 5년동안 코드를 유지하게 되는 사람인 것처럼 주석을 단다.
ASSERTION 참조 내용
c/c++ assertion.helper()
GetObjectType : GDI핸들에 대한 타입을 반환하는 GDI 서브 시스템 함수
IsBadCodePtr : 메모리가 실행될 수 있는지 확인
IsBadReadPtr : 명시된 수의 바이트에 대해 메모리 포인터가 읽을 수 있는지 확인
IsBadStringPtr : 스트링 포인터가 명시된 캐릭터의 최대 수나 스트링의 NULL 터미네이터까지 읽을 수 있는지 확인
IsBadWritePtr : 포인터가 명시된 바이트의 수에 대하여 기록할 수 있는지 확인
IsWindow : HWND 매개변수가 사용가능한 윈도우인지 확인
cf) IsBadStringPtr / IsBadWritePtr은 스레드에 민감, 스레드 안전을 대비해야함
visual basic assertion.hepler()
IsArray : 변수가 배열 타입인지 확인
IsDate : 변수가 날짜로 변환될 수 있는지 확인
IsEmpty : Variant 변수가 초기화 되었는지 확인
IsError : 변수가 오류 값을 가지고 있는지 확인
IsMissing : 옵션 Variant 인수가 프로시져 통과 했는지 확인
IsNull : Variant 변수가 NULL인지 확인
IsNumeric : 변수가 숫자 타입으로 변환될 수 있는지 확인
IsObject : 변수가 객체인지 확인
TypeName : 변수의 타입 이름을 반환
cf) ASSERT(발표용자료)
0 개의 댓글:
댓글 쓰기