rein's world

VisualStudio + UnitTest++에서 abort() 처리하기

전에 포스팅했던 Native C++ 코드 테스팅의 문제에서 계속.

일단 내가 파악한 VS 자체가 죽어버리는 — 그래서 VisualUnitTest++ (이하 VUTPP)가 처리하지 못하는 — 코드는 abort() 뿐인 듯 하다.1 그래서 MSDN을 좀 들여다보고는 abort() 가 *nix 시스템들 처럼 SIGABRT를 전달하는 방법으로 구현되어있…는 것처럼 보이는 정보를 얻었다.

그래서,

  • abort() 를 호출하는 UnitTest++ TEST 를 만들고,
  • SIGABRT를 처리하는 함수2를 단순히 std::exception("CRT called abort()") 를 던지는(throw) 함수로 작성
  • _set_abort_behavior(0, _WRITE_ABORT_MSG) 로 화면에 팝업(MessageBox)가 뜨는걸 방지
  • 테스트를 실행
  • Bingo!

abort()는 단순히 C++ 예외가 던져지는 것으로 판명되었고, UnitTest++이 예외를 잡아내는 것으로 끝냈다. 그리고 VUTPP역시 만족스럽게 테스트 실패 결과를 출력해줬다. 여튼, VisualStudio가 죽어버리는게 아니라 이런 테스트 실패 화면을 보게 된다.3

sigabrt

물론 assert의 경우엔 이 것만으론 조금 부족하다. 이렇게 처리해도 assertion fail에 대한 메시지 팝업이 뜨는데, 이건 ::_CrtSetReportHook2 같은 걸로 한 번 더 감싸줘야하지 않을까 싶다. 이것도 테스트 해봐야지.

ps. VS 2005에서 위 부분을 재현하는데 필요한 코드. Die안에는 abort()를 호출하는 부분이 들어있고, C++ 코드는 이런 형태.

void __cdecl sigabrt(int value) {
  throw std::exception("CRT called abort()");
}
...
// intercept abort()
signal(SIGABRT, sigabrt);
_set_abort_behavior(0, _WRITE_ABORT_MSG);

앞 부분에서 선언한 함수로 signal을 가로채서 abort의 원래 동작(프로세스 종료)을 막고, UnitTest++ 에서 이걸 인식할 수 있게 미리 정의한 예외를 던진다. 근데 이래도 정상 동작하는가에 대해서는 좀 궁굼하긴하다(…)


  1. <cassert>assert()도 결국엔 abort()를 부른다. ↩︎

  2. Unix에선 흔히 signal handler라고 부르는데 윈도우 쪽에선 뭐라고 부르는지 모르겠다. ↩︎

  3. VS 2005에선 한글 변수명/네임스페이스 명 등등을 허용하기 때문에, 네임스페이스나 클래스 이름에 해당하는 스윗/테스트 이름들을 한글로 하는게 가능하다. ↩︎