빌더에서 TRACE 사용하기

@codemaru · March 10, 2006 · 4 min read

빌더를 사용하면서 누구나 한번쯤 느꼈을 불편함 중에 하나가 TRACE가 없다는 점 입니다. 따라서 디버깅 출력을 하려면 모두 OutputDebugString으로 불편하게 확인을 해야 하죠. 그래서 이번에 XTRACE를 한번 만들어 봤습니다. 기본적인 아이디어는 MFC의 TRACE에서 가져왔습니다. TRACE보다 발전된 점은 없습니다... 단지 TRACE와 같은 것을 빌더에서 쓸 수 있게 했다 정도인 것 같습니다... ㅋㅋㅋ

XTRACE는 릴리즈 버전에는 자동으로 함수 호출 스텁이 제거되도록 설계되었기 때문에, 별도로 릴리즈 버전이라고 제거하실 필요는 없습니다. 또한 릴리즈 버전에서도 트레이스 구문을 확인하고 싶으신 경우에는 FORCE_XTRACE 매크로를 선언해 주시면 됩니다. 아래는 헤더 파일의 전체 소스 입니다. 트레이스 구문은 빌더에서는 Ctrl + Alt + V를 눌러서 이벤트 로거를 띄우면 표시됩니다. 별도로 실행한 경우에는 dbgview등의 프로그램을 확인이 가능합니다. dbgview 프로그램은 sysinternals.com에서 다운로드 가능합니다.

사용법은 간단합니다.

1.위의 헤더 파일을 다운로드 받으시거나 아래 소스를 긁어서 별도의 헤더 파일로 저장 하십시오.

  1. xtrace.h등으로 저장하신 후에 볼랜드 C++ 빌더의 기본 인클루드에 포함되어 있는 패스에 위 파일을 복사시켜 줍니다.

  2. XTRACE를 사용하고 싶으신 소스에서 헤더 파일을 인클루드 하시고 XTRACE 매크로를 사용하시면 됩니다.

#ifndef STRACE\_H   

#define STRACE\_H   

  

#include <windows.h>   

#if defined(\_DEBUG) || defined(FORCE\_XTRACE)   

  

#define XTRACE\_BUF\_SIZE 4096   

#define XTRACE          \_DbgPrintf   

  

inline void \_\_cdecl \_DbgPrintf(const char \*str, ...)   

{   

    char    buff[XTRACE\_BUF\_SIZE];   

    char    rbuff[XTRACE\_BUF\_SIZE];   

    DWORD   dwError;   

    va\_list    ap;   

  

    dwError = GetLastError();   

  

    va\_start(ap, str);   

    if(\_vsnprintf(buff, sizeof buff, str, ap) < 0)   

        buff[sizeof buff - 1] = 0;   

    va\_end(ap);   

  

    if(\_snprintf(rbuff, sizeof rbuff, "%sn", buff) < 0)   

        rbuff[sizeof rbuff - 1] = 0;   

  

    OutputDebugString(rbuff);   

    SetLastError(dwError);      

}   

  

  

#else   

  

#define XTRACE 1 ? (void) 0 : \_DbgPrintf   

inline void \_DbgPrintf(const char \*str, ...) {}   

  

#endif   

  

#endif

소스에 몇가지 테크닉을 소개하면 일단 _DbgPrintf가 가변 인자 함수로 구성되었다는 점을 들 수 있습니다. 따라서 printf와 같이 포맷 문자열을 사용해서 변수들을 출력할 수 있죠. 그리고 특징적인 점은 디버그 버전에서 XTRACE를 제거하는 구문입니다. 통상적으로 가변인자 매크로를 지원하지 않는 컴파일러의 경우 괄호를 두번 싸게해서 그 처리를 할 수 있지만, 여기서는 MFC형식을 따라서 인라인 함수로 _DbgPrintf를 선언하고 삼항 연산자를 사용해서 _DbgPrintf가 호출되지 않도록 했습니다. 쇼트서킷을 사용해서 XTRACE 0 && _DbgPrintf등으로 선언하셔도 무방합니다.

@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중